Reported issues for diffctx
Pod holds 18 of 20 GitHub reports that passed its relevance review. This can include external user reports, maintainer-confirmed bugs, and concrete feature gaps. Treat them as evidence to inspect, not a count of distinct defects.
Back to diffctx.
Most discussed
Agents do not call diffctx_context unprompted, and get little when they do
Observed 2026-09-23 while an agent (Claude Code) worked in this repo for a whole session with the diffctx MCP server installed: it never called diffctx_context until the owner asked why. Two calls made afterwards, on 1.17.0:
cc89b04b..a320ccaf(the session's real work:.github/workflows/*.yml+uv.lock) → 0 items. The repo's own.diffctx/ignorewithholds*.yml,*.yamlandtests, so CI/infra changes and test context are invisible here.373bbf3d..f047eeae(55 changed…
Read the thread · 2026-09-23 · closed · 11 comments
plugin: 1.18.0 hook pretooluse/posttooluse prints nothing where the CLI reports callers
Version: diffctx 1.18.0 release binary (the plugin's data/bin/diffctx-1.18.0), macOS arm64, 2026-10-01.
Observed. diffctx hook pretooluse and diffctx hook posttooluse print nothing, exit 0, write nothing to stderr, for every command tried — on a staged change whose impact is not empty. Same repository, same index, the CLI answers:
$ diffctx . --diff --mode impact -f md
diffctx impact for HEAD: 1 changed file(s), 49 caller(s) outside the diff, 43 untested
-…
[Read the thread](https://github.com/nikolay-e/diffctx/issues/323) · 2026-09-30 · closed · 4 comments
### Unprompted use is 0/260: inject a ≤2k impact table at commit/merge/push via hook instead of asking the model to call
**Summary.** A survey of 8 live agent sessions on 2026-09-29 (transcript-counted, ~260 code changes across a dozen repositories, diffctx 1.17.0 installed as plugin + CLI everywhere) found **0 unprompted calls** of `diffctx_context` or the plugin skills. Every one of the 7 calls that happened was forced by a QA checklist. Detailed tallies are on #289. This issue is the design conclusion, not more evidence.
**Why the model does not decide to call it (converging causes):**
1. The tool is deferred…
[Read the thread](https://github.com/nikolay-e/diffctx/issues/310) · 2026-09-29 · closed · 4 comments
### Self-diff impact-oracle mode (WIP patch -> callers/tests/blast radius)
> **Status 2026-09-22:** the presentation half shipped in 1.12.x (worktree input, blast-radius summary, impact groups). What remains is gated: scoring preset (Q-class), `mode=impact` (#127), latency (#134), acceptance eval (#128).
## Context
The unique wedge vs the query-seeded codegraph-MCP crowd: nobody answers questions about the patch the agent is writing *right now*. diffctx's native input is a diff; backward PPR / reverse edges already exist. Self-diff mode = agent calls diffctx on its…
[Read the thread](https://github.com/nikolay-e/diffctx/issues/135) · 2026-07-25 · closed · 4 comments
### Plugin impact hook goes silent for the rest of a session after a plugin upgrade (binary version mismatch, exit 0)
**Observed.** In one long Claude Code session (~65 commits, ~40 pushes, many of them multi-file), the plugin's PreToolUse/PostToolUse impact hook injected nothing, not once. Nothing told the agent the hook was inactive, so "no impact context" read as "nothing outside the diff".
**Why.** `hooks/diffctx-impact.sh` resolves `bin="$data/bin/diffctx-$version"`, where `$version` comes from the plugin root the session loaded at start. The plugin was upgraded 1.17.0 → 1.18.0 mid-session (the installer…
[Read the thread](https://github.com/nikolay-e/diffctx/issues/315) · 2026-09-29 · closed · 3 comments
### CLI default budget: unbounded dumps (145 KB) teach agents to skip the mandatory run
**Version:** diffctx 1.17.0, CLI `diffctx . --diff <range>` with no `--budget`.
**Observed.** Two sessions, counted from transcripts:
- a 28-file range with no `--budget` produced 145 KB (~36k tokens). The agent read only the section headers. A real bug (a gate reading a missing findings file as a clean pass) was inside the unread part and was found by hand a day later.
- the same class of range with `--budget 12000` produced 28 KB; the agent read all of it and caught a real off-by-cap bug in…
[Read the thread](https://github.com/nikolay-e/diffctx/issues/307) · 2026-09-29 · open · 3 comments
### locate on a CI YAML change returns only same-file proximity; referenced templates and sibling configs are absent
**Version:** diffctx 1.17.0 (MCP `diffctx_context`, `mode="locate"`)
**Range:** one commit in a Kubernetes/Argo infra repo that changes a single CI event-sensor YAML. It adds a second event dependency with an inline Lua filter and gives all 11 triggers an explicit `conditions:`.
**Observed:** all 142 returned items come from **the changed file itself**: 14 `changed` fragments plus 128 context fragments whose only reasons are `edge, proximity`. That is neighbouring blocks of the same YAML…
[Read the thread](https://github.com/nikolay-e/diffctx/issues/301) · 2026-09-27 · open · 3 comments
### Files excluded by .diffctx/ignore still surface as context fragments
## Observed
A path excluded via `.diffctx/ignore` is correctly dropped from `changed_files` and carries no `role: changed` — but the graph can still pull it back as a context fragment, content included.
repo/ .diffctx/ignore -> "excluded.py" keep.py (changed) excluded.py (changed, tracked)
`diffctx . --diff HEAD~1 --format yaml`:
```yaml
changed_files:
- keep.py # correct: excluded.py is absent
fragments:
- path: keep.py
role: changed
...
-…
[Read the thread](https://github.com/nikolay-e/diffctx/issues/173) · 2026-07-26 · closed · 2 comments
## Most recent
### impact/locate misses direct callers and reports tests:0 despite existing tests referencing the changed class
## Summary
On a Java Maven repo, `diffctx_context` (engine 1.18.2, build f5e2a42e) for diff `HEAD~1..HEAD` missed the direct call sites of the changed class entirely and reported `summary.tests = 0` even though test classes referencing the changed class exist in the repo.
## Environment
- diffctx 1.18.2 via MCP (`uvx --from 'diffctx[mcp]' diffctx-mcp`)
- Call: `diffctx_context(repo_path=..., diff_ref omitted, mode default)` — the repo had a clean tree, so HEAD was used; effective range was…
[Read the thread](https://github.com/nikolay-e/diffctx/issues/335) · 2026-10-02 · open · external user · 0 comments
### `diffctx-mcp` lacks `--version`/`-v` despite exposing package version to MCP clients
## Summary
`diffctx-mcp` rejects `--version` even though the main CLI supports version reporting and the MCP server already imports `diffctx.version.__version__` and injects it into the MCP server metadata.
Observed on **diffctx 1.18.2**.
## Reproduction
```bash
diffctx --version
diffctx-mcp --version
Observed:
diffctx 1.18.2
usage: diffctx-mcp [-h]
diffctx-mcp: error: unrecognized arguments: --version
The MCP server itself is installed and functional; only the executable…
Read the thread · 2026-10-02 · open · 0 comments
Plain diffctx install exposes diffctx-mcp executable that crashes without MCP extras
Summary
Installing the base package creates both diffctx and diffctx-mcp console scripts, but the latter is not runnable unless the optional mcp extra was installed. The result is a published executable that fails immediately with a Python traceback.
Observed on diffctx 1.18.2 on macOS arm64.
Reproduction
uv tool install --force 'diffctx@latest'
diffctx --version
diffctx-mcp --help
Base CLI succeeds:
diffctx 1.18.2
MCP entrypoint fails because its…
Read the thread · 2026-10-02 · open · 0 comments
impact: an import-only fragment is listed as a caller and counted UNTESTED
Version: diffctx 1.18.0, diffctx . --diff 0d75e73a..ae7b4886 --mode impact -f md on this repository (the 1.18.0 epoch: 53 changed files).
Observed. Under src/diffctx/mcp/server.py::diffctx_context the impact lists
- called from src/diffctx/mcp/legacy.py:1-28 — UNTESTED
Lines 1-28 of that file are the module docstring and the import block; nothing there calls diffctx_context. The import edge from the language builder reaches the changed symbol, the fragment has no symbol…
Read the thread · 2026-09-29 · closed · 1 comment
plugin: identical impact block injected five times in one commit sequence
Version: diffctx 1.17.0, Claude Code plugin hooks, 2026-09-29.
Observed: in one commit sequence on an unchanged working tree the plugin injected the same impact block five times, ~1.5k tokens each, byte-identical apart from the range label (HEAD vs HEAD..<index sha>):
- PostToolUse after
git status --short - PostToolUse after
git diff --cached --numstat - PostToolUse after
git add -A && git diff --cached --stat - PreToolUse before
git commit(failed on a formatter hook) -…
Read the thread · 2026-09-29 · closed · 1 comment
Kotlin files are all 'unparsed': locate returns text excerpts only, confidence 0.09
Observed (diffctx 1.17.0, build bf723ad0, MCP diffctx_context, mode=locate, budget_tokens=6000) on a one-commit range in a Kotlin/Spring backend: 11 changed files, 10 of them .kt.
coverage.unparsed_fileslists all 10 Kotlin files;confidenceis 0.09.- Every changed Kotlin fragment comes back as
kind: excerptorchunkwithscore: 0.0— no function/class fragments, no symbol-level edges. - The context that would have explained the change was reachable only…
Read the thread · 2026-09-29 · open · 1 comment
--diff drops a file the range deletes: no fragment, no deletion marker
Observed with diffctx . --diff 6ff54b5f..25f66008 on nikolay-e/yay-tsa (diffctx from $PATH, 2026-09-28).
git diff --name-only lists 34 files; the context covers 33. The one missing is a file the range deletes outright: apps/backend/infra-karaoke-worker/src/main/kotlin/dev/yaytsa/worker/karaoke/KaraokePriorityQueue.kt (0 insertions, 70 deletions). There is no fragment for it and no line saying it was removed.
A deletion is part of what a change does. Here the removed class held the…
Read the thread · 2026-09-28 · closed · 1 comment
locate: serialized response is ~3x budget_tokens and overflows the MCP client on a one-file commit
Version: diffctx 1.17.0 (MCP diffctx_context, Claude Code plugin)
Command: diffctx_context(repo_path=<infra repo>, diff_ref=<sha>^..<sha>, mode="locate"), all other arguments at their defaults (budget_tokens=8000, max_tokens=25000).
Range: one commit that changes a single 800-line YAML file: 14 changed lines (a new event dependency and a conditions: line on 11 triggers).
Observed: the result has 142 items whose tokens add up to 7,879, which is inside the…
Read the thread · 2026-09-27 · open · 1 comment
diffctx_context returns a JSON string, so MCP clients get the locate document double-encoded in {"result": ...}
diffctx_context is declared -> str and returns json.dumps(doc) (mcp/server.py:142). FastMCP wraps a string return as structured output {"result": "<string>"}, so the client receives the locate document JSON-encoded inside a JSON string:
{"result":"{\"schema\":\"diffctx.locate.v1\",\"name\":\"...\",\"items\":[{\"path\":\"src/...\", ...
Every quote is escaped once more, so the payload costs more tokens than the document itself, and a model has to mentally decode it before it…
Read the thread · 2026-09-25 · closed · 0 comments
MCP server breaks after an in-place upgrade: lazy imports hit the new package tree
Observed 2026-09-26: uv tool install --force "diffctx[mcp]@latest" (1.16.0 → 1.17.0) while a Claude Code session held the MCP server (diffctx mcp) open. The next diffctx_context call failed with:
Error executing tool diffctx_context: No module named 'diffctx.tokens'
The running process kept the 1.16.0 modules it had already imported, but the tool body imports lazily (from diffctx.tokens import count_tokens in mcp/server.py:81, from .fetch import fetch_result at :254, `from…
Read the thread · 2026-09-25 · closed · 0 comments
The remaining reports are on the project's issue tracker.