Egonex-AI/Understand-Anything · error · Error
Invalid assembled graph
Error message
Invalid assembled graph
What it means
`validateIncrementalSymbols` loads `assembled-graph.json` (unless a graph was passed in) and requires both `graph.nodes` and `graph.edges` to be arrays before hashing and validating it. If either is missing or not an array, the graph is structurally unusable and it throws 'Invalid assembled graph'.
Source
Thrown at understand-anything-plugin/skills/understand/validate-incremental-symbols.mjs:325
// Git compares normalized contents, including repository clean/EOL rules.
if (paths.length) git(projectRoot, [
'diff', '--quiet', '--no-ext-diff', plan.headCommit, '--', ...paths.map(path => `:(literal)${path}`),
]);
return { plan, baseline };
}
export async function validateIncrementalSymbols(projectRoot, { graph, intermediateDir } = {}) {
const core = await getCore();
intermediateDir ??= join(core.resolveUaDir(projectRoot), 'intermediate');
const reportPath = join(intermediateDir, 'incremental-symbol-report.json');
const report = { version: 1, ok: false, files: [], unresolvedFiles: [], errors: [] };
const graphFromDisk = graph === undefined;
try {
const { plan, baseline } = loadSymbolContext(projectRoot, intermediateDir);
report.baseCommit = plan.baseCommit;
report.headCommit = plan.headCommit;
graph ??= readJson(join(intermediateDir, 'assembled-graph.json'));
if (!Array.isArray(graph.nodes) || !Array.isArray(graph.edges)) throw new Error('Invalid assembled graph');
report.graphHash = createHash('sha256').update(JSON.stringify(graph)).digest('hex');
let parser;
const evidenceByPath = new Map();
const parseHead = async path => {
if (evidenceByPath.get(path)?.head) return evidenceByPath.get(path).head;
if (!parser) {
parser = new core.TreeSitterPlugin(core.builtinLanguageConfigs.filter(config => config.treeSitter));
await parser.init();
}
// :./ keeps git-show relative to projectRoot, including monorepo subdirectories.
const headContent = git(projectRoot, ['show', `${plan.headCommit}:./${path}`]);
const evidence = { head: parser.analyzeFileStrict(path, headContent) };
evidenceByPath.set(path, evidence);
return evidence.head;
};
const parseRevisions = async path => {
await parseHead(path);
const evidence = evidenceByPath.get(path);View on GitHub (pinned to 07edf82a04)
Solutions
- Regenerate `assembled-graph.json` by re-running the graph assembly step.
- Validate the JSON shape: it must contain `nodes: []` and `edges: []` (`jq '.nodes|type, .edges|type' assembled-graph.json`).
- If passing a graph programmatically, ensure it includes array-valued `nodes` and `edges`.
- Check disk space / write errors if the file appears truncated, and re-run assembly after cleanup.
Example fix
// before: passing a bare object
await validateIncrementalSymbols({ projectRoot, intermediateDir, graph: {} });
// after: pass a complete graph or let it load from disk
const graph = JSON.parse(readFileSync(join(intermediateDir, 'assembled-graph.json'), 'utf8'));
if (!Array.isArray(graph.nodes) || !Array.isArray(graph.edges)) throw new Error('bad graph');
await validateIncrementalSymbols({ projectRoot, intermediateDir, graph }); Defensive patterns
Strategy: type-guard
Validate before calling
const graph = JSON.parse(readFileSync(join(intermediateDir,'assembled-graph.json'),'utf8'));
if (!Array.isArray(graph.nodes) || !Array.isArray(graph.edges)) {
await rerunGraphAssembly();
} Type guard
function isValidGraph(g) {
return g != null && typeof g === 'object'
&& Array.isArray(g.nodes) && Array.isArray(g.edges);
} Try / catch
try {
await validateIncrementalSymbols({ projectRoot, intermediateDir });
} catch (err) {
if (err.message === 'Invalid assembled graph') {
await rerunGraphAssembly(); // rebuild assembled-graph.json
} else throw err;
} Prevention
- Write assembled-graph.json atomically (temp file + rename) so crashes never leave partial output.
- Validate graph JSON shape right after assembly.
- Check disk space before large graph writes.
- When passing a graph programmatically, run a shape guard first.
When it happens
Trigger: Calling `validateIncrementalSymbols` when `assembled-graph.json` in the intermediate directory is absent-but-replaced by malformed JSON output, truncated, or written without `nodes`/`edges` array fields — or when a caller passes a `graph` argument lacking those arrays.
Common situations: The graph-assembly agent crashed mid-write leaving a partial file; disk-full truncated the JSON; an older schema stored nodes under a different key; a caller passed a hand-built object like `{}` instead of a full graph.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- A valid previous graph is required for incremental symbol pr
- Architecture update requires layers.json; baseline not advan
- Architecture update requires tour.json; baseline not advance
- Unresolved incremental symbol loss; baseline not advanced
- Import extraction reported failures: ${preview}${suffix}
AI-assisted analysis of Egonex-AI/Understand-Anything@07edf82a04 (2026-09-07).
Data as JSON: /api/errors/6e8f7dbb2f14048c.
Report an issue: GitHub.