You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
When running /graphify in Claude Code, the semantic extraction step (Step 3B) silently fails for a majority of chunks when the coordinator dispatches to the Explore subagent type. The skill template's wording does not specify an agent type, so the model can pick Explore for parallel dispatch — which is read-only and cannot write the chunk output files the coordinator expects.
Environment
graphifyy 0.4.0 (installed via pipx install --python python3.13 graphifyy)
Claude Code (Opus 4.6, 1M context)
Skill installed via graphify install → ~/.claude/skills/graphify/SKILL.md
macOS 14, Python 3.13.12
What happened
Dispatched 12 parallel subagents in one message for a ~470k-word corpus (mas codebase, 674 files). Used Agent(subagent_type="Explore", ...) because Explore is the recommended type for "exploring/reading" work in Claude Code.
Result: only 5 of 12 chunks actually wrote graphify-out/.graphify_chunk_NN.json to disk. The other 7 agents responded with inline JSON in their text output, a mix of:
JSON in a fenced code block followed by the words "chunk N written" (coordinator has to parse this back out)
JSON with extra commentary before/after ("Here's the extraction: …")
Narrative analysis with no JSON at all (one of the image chunks literally responded: "I cannot create the output file as I'm in read-only mode.")
A heredoc (cat > ... << EOF) that never executed because Explore has no Bash tool
I had to salvage 5 chunks from agent response text, and hand-reconstruct 2 image chunks from narrative descriptions.
A subsequent re-run on the same corpus with subagent_type="general-purpose" (which has Write/Bash access) completed all 12 chunks cleanly:
Metric
First run (Explore)
Re-run (general-purpose)
Delta
Semantic nodes
198
469
2.4×
Semantic edges
155
542
3.5×
Hyperedges
11
27
2.5×
Chunks wrote to disk
5 / 12
12 / 12
✅
The first run silently under-counted by more than half. A user who didn't spot-check .graphify_chunk_*.json on disk would never know.
Why the skill template is susceptible
Relevant excerpt from Step B2 in graphify/skill.md:
Step B2 — Dispatch ALL subagents in a single message
Call the Agent tool multiple times IN THE SAME RESPONSE — one call per chunk. …
Each subagent receives this exact prompt … Output exactly this JSON (no other text):
The prompt tells the subagent to "output exactly this JSON" but does not instruct the coordinator on:
Which subagent type to use. On Claude Code, general-purpose has Write/Bash; Explore does not. The skill picks whichever type the model thinks fits the verb "extract", and "extract" sounds read-only.
Whether the subagent should write the JSON to a file or return it inline. The skill template is ambiguous — the per-subagent prompt says "output exactly this JSON" (sounds inline) but the coordinator's Step B3 reads from per-chunk files (.graphify_chunk_NN.json), implying disk.
How the coordinator should distinguish "agent returned JSON inline" from "agent wrote to disk" when merging. Currently: it doesn't. If the file is missing, the chunk is lost silently.
In my case the model picked Explore based on surface-level read-only semantics ("you are reading files and extracting"), and silently lost 7 chunks.
Suggested fix (small, skill.md only)
Two changes to Step B2:
1. In the coordinator dispatch instructions, specify the subagent type explicitly:
Claude Code users: use subagent_type="general-purpose" when dispatching. Do NOT use Explore — it is read-only and cannot write the chunk files. On Codex, use the default agent. On other platforms, use whichever subagent type has Write/Bash access.
2. In the per-subagent prompt, change the output instruction from "Output exactly this JSON" to:
Use the Write tool to save the JSON to graphify-out/.graphify_chunk_NN.json. Do NOT print the JSON in your response. Reply only with "chunk NN written" so the coordinator can merge.
Then in Step B3, the merge logic is already correct (it reads per-chunk files from disk) — it just needs to warn when a chunk file is missing rather than silently skipping.
This makes the pipeline robust to agent-response format drift and gives the coordinator a single reliable signal: file exists on disk = success.
Related
Issue collect_files() in extract.py ignores .graphifyignore #188 ("collect_files() in extract.py ignores .graphifyignore") — I hit this too; .graphifyignore worked at the top level but deeper **/coverage/ patterns required explicit paths. Separate from this bug, but worth cross-referencing if you're touching file enumeration.
Workaround for users on Claude Code today
If you're running /graphify in Claude Code today, explicitly tell Claude at the start of the invocation: "use subagent_type='general-purpose' for the graphify extraction dispatch". Claude will honor it, and you'll get full semantic extraction on the first try.
Happy to open a PR for the skill.md fix if it'd be useful — it's a ~4-line change.
Summary
When running
/graphifyin Claude Code, the semantic extraction step (Step 3B) silently fails for a majority of chunks when the coordinator dispatches to theExploresubagent type. The skill template's wording does not specify an agent type, so the model can pickExplorefor parallel dispatch — which is read-only and cannot write the chunk output files the coordinator expects.Environment
graphifyy0.4.0 (installed viapipx install --python python3.13 graphifyy)graphify install→~/.claude/skills/graphify/SKILL.mdWhat happened
Dispatched 12 parallel subagents in one message for a ~470k-word corpus (mas codebase, 674 files). Used
Agent(subagent_type="Explore", ...)becauseExploreis the recommended type for "exploring/reading" work in Claude Code.Result: only 5 of 12 chunks actually wrote
graphify-out/.graphify_chunk_NN.jsonto disk. The other 7 agents responded with inline JSON in their text output, a mix of:cat > ... << EOF) that never executed becauseExplorehas noBashtoolI had to salvage 5 chunks from agent response text, and hand-reconstruct 2 image chunks from narrative descriptions.
A subsequent re-run on the same corpus with
subagent_type="general-purpose"(which has Write/Bash access) completed all 12 chunks cleanly:Explore)general-purpose)The first run silently under-counted by more than half. A user who didn't spot-check
.graphify_chunk_*.jsonon disk would never know.Why the skill template is susceptible
Relevant excerpt from Step B2 in
graphify/skill.md:The prompt tells the subagent to "output exactly this JSON" but does not instruct the coordinator on:
general-purposehasWrite/Bash;Exploredoes not. The skill picks whichever type the model thinks fits the verb "extract", and "extract" sounds read-only..graphify_chunk_NN.json), implying disk.In my case the model picked
Explorebased on surface-level read-only semantics ("you are reading files and extracting"), and silently lost 7 chunks.Suggested fix (small,
skill.mdonly)Two changes to Step B2:
1. In the coordinator dispatch instructions, specify the subagent type explicitly:
2. In the per-subagent prompt, change the output instruction from "Output exactly this JSON" to:
Then in Step B3, the merge logic is already correct (it reads per-chunk files from disk) — it just needs to warn when a chunk file is missing rather than silently skipping.
This makes the pipeline robust to agent-response format drift and gives the coordinator a single reliable signal: file exists on disk = success.
Related
collect_files()inextract.pyignores.graphifyignore") — I hit this too;.graphifyignoreworked at the top level but deeper**/coverage/patterns required explicit paths. Separate from this bug, but worth cross-referencing if you're touching file enumeration.Workaround for users on Claude Code today
If you're running
/graphifyin Claude Code today, explicitly tell Claude at the start of the invocation: "usesubagent_type='general-purpose'for the graphify extraction dispatch". Claude will honor it, and you'll get full semantic extraction on the first try.Happy to open a PR for the
skill.mdfix if it'd be useful — it's a ~4-line change.