Skip to main content
This guide covers common errors, build failures, and performance issues you may encounter when using Refractor.

Configuration Errors

Error:
ConfigException: Configuration file not found: /path/to/refractor.yaml
Run "refractor init" to create one.
Cause: Refractor requires a refractor.yaml file and fails fast if it’s missing.Source: lib/src/config/config_manager.dart:18-24Solution:Create a configuration file:
refractor init
Or specify a custom path:
refractor build --config path/to/config.yaml
Error:
ConfigException: Configuration file is empty: /path/to/refractor.yaml
Cause: The config file exists but contains no content.Source: lib/src/config/config_manager.dart:35-39Solution:Populate the file with at least minimal configuration:
refractor:
  symbol_map: symbol_map.json

passes:
  rename: true
Error:
ConfigException: Invalid configuration at /path/to/refractor.yaml: ...
Cause: YAML syntax error or invalid structure.Source: lib/src/config/model/refractor_config.dart:36-59Solution:Validate YAML syntax:
  • Check for correct indentation (use spaces, not tabs)
  • Ensure colons have spaces after them
  • Verify all quoted strings are properly closed
Use a YAML validator or run:
refractor build --verbose
The verbose flag provides detailed error context.
Error:
ConfigException: Configuration root must be a YAML mapping/object.
Cause: The YAML file starts with a list or scalar instead of a map.Source: lib/src/config/model/refractor_config.dart:48-52Solution:Ensure your config starts with top-level keys:
refractor:
  symbol_map: symbol_map.json

passes:
  rename: true
Error:
ConfigException: Unknown pass: "my_pass"
Cause: Referenced a pass name that doesn’t exist.Source: lib/src/config/model/refractor_config.dart:113Solution:Only use valid pass names:
  • rename
  • string_encrypt
  • dead_code
Available passes are defined in:
static List<Pass> passesFromNames(List<String> names) {
  final available = <String, Pass>{
    'rename': RenamePass(),
    'string_encrypt': StringEncryptPass(),
    'dead_code': DeadCodePass(),
  };
  // ...
}
Source: lib/src/config/model/refractor_config.dart:105-116

Build Failures

Error:
BuildException: Invalid target: xyz
Cause: Specified an unsupported build target.Source: lib/src/engine/compiler/compiler.dart:26Solution:Use only valid targets:
  • exe - Native executable
  • aot - AOT snapshot (.aot)
  • jit - JIT snapshot (.jit)
  • kernel - Kernel bytecode (.dill)
refractor build --target exe
See the Build Targets guide for details.
Error:
FileIoException: Input file not found: lib/main.dart
Cause: The specified entrypoint doesn’t exist.Exit code: ExitCode.ioError.codeSource: lib/src/exceptions/refractor_exception.dart:64-69Solution:Verify the input file exists:
ls -la lib/main.dart
Specify the correct path:
refractor build --input bin/main.dart
Error:
CompilationException: Failed to compile to kernel
Cause: Syntax errors, missing dependencies, or other Dart compilation issues.Exit code: ExitCode.software.codeSource: lib/src/exceptions/refractor_exception.dart:47-52Solution:First, verify your code compiles normally:
dart compile exe lib/main.dart
Fix any compilation errors, then retry with Refractor:
refractor build
Run with --verbose for detailed compiler output:
refractor build --verbose
Error:
ProcessRunException: Failed to execute dart compile
Cause: Underlying process (dart compile) failed to run.Exit code: ExitCode.software.codeSource: lib/src/exceptions/refractor_exception.dart:54-60Solution:Ensure Dart SDK is properly installed:
dart --version
Check PATH environment variable includes Dart:
which dart
Reinstall Dart SDK if necessary.

Pass-Specific Issues

Issue: Code using dart:mirrors or reflection fails after renaming.Cause: The rename pass obfuscates identifiers, breaking code that relies on original names at runtime.Solution:
1

Identify reflection usage

Search for:
  • dart:mirrors imports
  • runtimeType.toString()
  • String-based lookups (e.g., JSON serialization)
2

Exclude generated files

Add exclusions to refractor.yaml:
refractor:
  exclude:
    - "**/*.g.dart"
    - "**/*.freezed.dart"
    - "**/models/**"
3

Preserve main entrypoint

Ensure preserve_main is enabled:
passes:
  rename:
    preserve_main: true
Source: lib/src/config/model/refractor_config.dart:73
Issue: Encrypted strings cause runtime issues with URLs or API endpoints.Cause: String encryption XORs all string literals, including those that must remain readable.Solution:Exclude patterns from encryption:
passes:
  string_encrypt:
    xor_key: 0x5A
    exclude_patterns:
      - "^https://"
      - "^http://"
      - "^wss://"
      - "^ws://"
      - "^package:"
Source: lib/src/config/model/refractor_config.dart:74-75
Issue: Dead code injection changes program behavior unexpectedly.Cause: The dead code pass inserts unreachable branches that should never execute, but edge cases may trigger them.Solution:Reduce insertion frequency:
passes:
  dead_code:
    max_insertions_per_procedure: 1
Or disable the pass entirely for testing:
passes:
  dead_code: false
Source: lib/src/config/model/refractor_config.dart:90-92

Performance Issues

Issue: Obfuscation takes significantly longer than normal compilation.Cause: Multiple passes traverse the entire kernel AST, especially on large codebases.Solution:
1

Profile which passes are slow

Enable verbose logging:
refractor build --verbose
This shows detailed timing for each step:
Compiling lib/main.dart to kernel...
Running obfuscation passes...
Writing obfuscated kernel...
Compiling to target exe...
Build complete: build/app
Source: lib/src/engine/engine.dart:44-76
2

Disable unnecessary passes

If a pass isn’t critical, disable it:
passes:
  rename: true
  string_encrypt: false  # Disable if not needed
  dead_code: false       # Often the slowest
3

Exclude large generated files

Generated code often doesn’t need obfuscation:
refractor:
  exclude:
    - "**/*.g.dart"
    - "**/*.freezed.dart"
    - "**/generated/**"
Issue: Obfuscated executable is much larger than expected.Cause: Dead code injection adds extra bytecode, or you’re using the exe target.Solution:
1

Use a smaller target format

Switch from exe to aot or jit:
refractor build --target aot
See Build Targets for size comparison.
2

Reduce dead code insertions

Lower the insertion rate:
passes:
  dead_code:
    max_insertions_per_procedure: 1
3

Strip debug symbols (for exe)

On Linux/macOS, strip the binary:
strip build/app
Issue: Obfuscated app runs slower than the original.Cause: String encryption adds XOR decoding overhead, and dead code may impact branch prediction.Solution:
1

Use AOT target for best performance

AOT compilation produces the fastest code:
refractor build --target aot
2

Benchmark with and without string encryption

Disable string encryption and measure:
passes:
  rename: true
  string_encrypt: false
  dead_code: true
3

Profile the application

Use Dart’s profiling tools to identify bottlenecks:
dart run --observe build/app.jit
Then connect to Observatory to profile.

Exception Types Reference

Refractor defines specific exception types with appropriate exit codes:
ExceptionExit CodeCommon Causes
ConfigExceptionExitCode.config.codeMissing/invalid config file, YAML errors
BuildExceptionExitCode.software.codeInvalid target, orchestration errors
CompilationExceptionExitCode.software.codeDart compilation failures
ProcessRunExceptionExitCode.software.codeProcess execution failures
FileIoExceptionExitCode.ioError.codeMissing files, inaccessible directories
Source: lib/src/exceptions/refractor_exception.dart:7-69

Debugging Tips

Use --verbose flag

Get detailed output for each build step:
refractor build --verbose

Inspect kernel output

Examine obfuscated bytecode:
refractor inspect build/app.dill

Build incrementally

Enable passes one at a time to isolate issues:
passes:
  rename: true
  string_encrypt: false
  dead_code: false

Compare outputs

Build with and without obfuscation and diff the results:
dart compile exe lib/main.dart -o build/plain
refractor build --target exe

Getting Help

If you encounter an issue not covered here:
  1. Check the logs - Use --verbose to get detailed output
  2. Verify your configuration - Ensure refractor.yaml is valid
  3. Test without obfuscation - Confirm your code compiles normally with dart compile
  4. Report the issue - Open an issue at github.com/yardexx/refractor
When reporting issues, include:
  • Refractor version
  • Full error message
  • refractor.yaml configuration
  • Minimal reproduction steps

Next Steps

Build Targets

Choose the right output format

Debugging

Deobfuscate stack traces with symbol maps

Build docs developers (and LLMs) love