Skip to main content
If a report looks wrong, start with a small file pair and compare terminal and JSON output. Keep stderr too: semantic fallback notes are separate from stdout.

Build fails

Use the repository’s pinned toolchain and install a C/C++ compiler for Tree-sitter/scanners. Initial builds need access to Cargo dependencies. Keep Cargo.lock unchanged unless deliberately updating dependencies. Report the compiler error and target platform.

A code file uses line diff

Run differens languages. Code classification does not guarantee a linked grammar. Unsupported extensions, parser failures, source/depth limits, and tree node budgets can trigger line fallback. Check stderr diagnostics or machine-output fallback metadata. The CLI has no flag to raise parser budgets. Library callers can choose matching limits, but larger budgets may increase time and memory costs.

Changes appear as deletion and insertion

Matching uses structural evidence and conservative recovery. A major rewrite or changed declaration shape may not establish identity. JSON exposes underlying actions, while human formats group them into readable constructs. A move or extraction cannot always be inferred safely.

Git comparison fails

Check the repository and refs with Git itself, then rerun from the intended checkout. Read errors and Git command failures return nonzero instead of silently producing an unchanged result. Direct file and directory modes work outside repositories.

Driver stopped working after reinstall

install-git-driver records the executable path in local Git configuration. Run it again after moving or replacing the binary. Existing unrelated .gitattributes rules are retained.

Memory grows on a large changeset

Native workers process bounded windows, but a single large file and retained cross-file candidates can still be large. --jobs=1 reduces simultaneous parser work. NDJSON begins reporting before the entire changeset completes; it does not imply constant memory for correlation.

Machine output has an unexpected shape

Standalone file JSON is an array; directory/repository JSON is an envelope. An unchanged comparison produces [] or empty envelope arrays. NDJSON emits file objects and an optional cross-file trailer; unchanged inputs produce no records. Read machine outputs before consuming it.

Diff is slower than expected

Compare a focused file pair to separate parsing/matching cost from repository I/O. For a large changeset, try one worker and streaming output:
Lower concurrency reduces simultaneous parser work; it is not guaranteed to be faster. The default chooses one or two workers. Windows contain at most 24 files with a soft 64 MiB source budget, and each worker has a bounded parse cache. Cross-file candidates spill after an 8 MiB accounted cache, so temporary-disk capacity and I/O can also matter. Use the benchmark guide to measure a release build rather than infer a speedup from the implementation language.

Deep nesting falls back to lines

Core tree ownership, traversal, matching, and cleanup use flat storage or explicit stacks. Parsers have their own limits: semantic code routing uses a 50,000-node limit per tree and a 1,000,000-byte source limit per side, and code conversion has a depth budget. Data and markup parsers also enforce construction/depth budgets. A safe core does not make every parser accept unlimited nesting. A note such as this means the CLI compared lines instead:
Retain the fallback metadata and a reduced input when reporting a parser issue. The CLI has no flag to raise those limits.

YAML nesting looks wrong

The native YAML parser accepts valid four-space nesting; it no longer relies on a two-space-only subset. Tabs used for YAML indentation remain invalid YAML. Compare the actual file paths and inspect stderr to see whether parsing fell back. A .txt file containing YAML is still classified as prose. The structured-data example shows four-space YAML nesting with captured output. Keep valid YAML unchanged when reducing a reproducer; reformatting it first can hide the issue.

Markup attributes look wrong

Quoted > characters are handled as part of attribute values, and non-label attributes such as href are compared. The old advice to escape every quoted > is not needed for the native tokenizer. See the markup example. The markup parser is lenient rather than a full browser parser. If malformed markup produces a surprising tree, preserve the smallest failing document and compare its JSON actions. A parse failure can use lines; a partial parsed tree may instead contain structural edits.

Rust compiler or editor errors

Run the workspace compiler check, then a focused test:
A changed shared API can break consumers in several crates. Keep the pinned toolchain and lockfile when reproducing the failure. Node/Bun typecheck and build commands from historical releases do not apply to this workspace.

Still stuck?

Open an issue with:
  • differens --version, your platform, and whether you built from source.
  • The exact command and whether it compared files, directories, or Git refs.
  • Minimal input files, expected output, observed output, and stderr notes.
  • The JSON actions if the human grouping hides the detail you need to explain.
The roadmap tracks product limits; the migration guide lists intentional differences from the earlier implementation.