{"record":{"id":"325c23f5c6c2cdad","repo":"affaan-m/ECC","slug":"node-id-mismatch-name","errorCode":null,"errorMessage":"Node id mismatch: {name}","messagePattern":"Node id mismatch: (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"skills/taste-application/scripts/workflow_graphs.py","lineNumber":80,"sourceCode":"def references_in(value):\n    if isinstance(value, str) and value.startswith('$'):\n        yield value[1:].split('.')\n    elif isinstance(value, dict):\n        for child in value.values():\n            yield from references_in(child)\n    elif isinstance(value, list):\n        for child in value:\n            yield from references_in(child)\n\n\ndef validate_graph(graph):\n    \"\"\"Verify dependencies and every declared input; endpoint schemas need live QA.\"\"\"\n    contents = graph['contents']\n    nodes, inputs = contents['nodes'], contents['schema']['input']\n    used = set()\n    for name, node in nodes.items():\n        if node['id'] != name:\n            raise ValueError(f'Node id mismatch: {name}')\n        for dependency in node.get('depends', []):\n            if dependency != 'input' and dependency not in nodes:\n                raise ValueError(f'Unknown dependency: {dependency}')\n    ancestors = {}\n\n    def visit(name, stack):\n        if name == 'input':\n            return set()\n        if name in stack:\n            raise ValueError('Dependency cycle')\n        if name not in ancestors:\n            deps = nodes[name].get('depends', [])\n            ancestors[name] = set(deps).union(*(visit(dep, stack | {name}) for dep in deps))\n        return ancestors[name]\n\n    for name, node in nodes.items():\n        reachable = visit(name, set())\n        for ref in references_in({'input': node.get('input'), 'fields': node.get('fields')}):","sourceCodeStart":62,"sourceCodeEnd":98,"githubUrl":"https://github.com/affaan-m/ECC/blob/8321021c54d670126ce3b2969d5deb880b4b0c2a/skills/taste-application/scripts/workflow_graphs.py#L62-L98","documentation":"validate_graph checks that each entry key in contents['nodes'] matches that node's declared 'id' field. A mismatch means the graph JSON's node map key and internal id have drifted — references by name would resolve incorrectly, so load_graph refuses the graph with this ValueError.","triggerScenarios":"Loading a hand-edited or generated graph JSON where a node's 'id' field was changed (or its dict key renamed) so node['id'] != key, then calling load_graph.","commonSituations":"Renaming a node in one place (key or id) but not the other; a code generator emitting inconsistent ids; merge conflict leaving key/id divergent.","solutions":["Set the node's 'id' field to exactly match its key in the nodes dict (or vice versa)","Re-generate the graph JSON from the canonical builder to restore key/id consistency","Run a pre-check comparing each node key to node['id'] before load_graph"],"exampleFix":"// before\n{\"nodes\": {\"probe\": {\"id\": \"probe_v2\", ...}}}\n// after\n{\"nodes\": {\"probe\": {\"id\": \"probe\", ...}}}","handlingStrategy":"validation","validationCode":"def check_node_ids(graph):\n    for name, node in graph['contents']['nodes'].items():\n        if node['id'] != name:\n            raise ValueError(f'Node id mismatch: {name}')","typeGuard":"def ids_consistent(graph) -> bool:\n    nodes = graph['contents']['nodes']\n    return all(node.get('id') == name for name, node in nodes.items())","tryCatchPattern":"try:\n    graph = load_graph(path)\nexcept ValueError as e:\n    if 'Node id mismatch' in str(e):\n        print(f'Graph JSON inconsistent, fix key/id: {e}')\n    else:\n        raise","preventionTips":["Rename nodes with a script that updates both the dict key and the id field","Validate graph JSON with a schema/lint in CI before load_graph","Avoid hand-editing generated graphs; regenerate from the builder"],"tags":["validation","graph","schema"],"backgroundTag":"schema-validation-failed","analyzedSha":"8321021c54d670126ce3b2969d5deb880b4b0c2a","analyzedAt":"2026-09-16T10:08:13.343Z","contentChangedAt":"2026-09-16T10:08:13.343Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}