Skip to content

fix(serve): reorder except clauses so the corrupted-graph message is reachable#2017

Open
kimdzhekhon wants to merge 2 commits into
Graphify-Labs:v8from
kimdzhekhon:fix/serve-json-decode-error-order-2005
Open

fix(serve): reorder except clauses so the corrupted-graph message is reachable#2017
kimdzhekhon wants to merge 2 commits into
Graphify-Labs:v8from
kimdzhekhon:fix/serve-json-decode-error-order-2005

Conversation

@kimdzhekhon

Copy link
Copy Markdown

Summary

  • json.JSONDecodeError subclasses ValueError, so _load_graph()'s except (ValueError, FileNotFoundError) clause always matched first — the except json.JSONDecodeError clause with the "graph.json is corrupted (...). Re-run /graphify to rebuild." recovery message was unreachable dead code.
  • Users hitting a truncated/corrupted graph.json got the bare underlying json.JSONDecodeError message instead, contradicting what SECURITY.md documents for this exact threat.
  • Moved the json.JSONDecodeError clause first so it actually catches. Audited the rest of serve.py's exception handlers for the same narrower-after-broader ordering bug — found no other instance.

Fixes #2005.

Test plan

  • Added test_load_graph_corrupted_json_prints_recovery_message — writes invalid JSON, asserts the recovery message (not the bare decode error) is printed
  • uv run pytest tests/test_serve.py -q -k load_graph — 6 passed
  • uv run pytest tests/ -q — full suite: 3412 passed (5 pre-existing failures unrelated to this change, missing optional openai dependency in this environment)

…reachable

json.JSONDecodeError subclasses ValueError, so the broader
`except (ValueError, FileNotFoundError)` clause always matched first,
making the intended "graph.json is corrupted (...). Re-run /graphify
to rebuild." recovery hint dead code — users with a truncated graph.json
got the bare json.JSONDecodeError message instead, contradicting the
behavior SECURITY.md documents for this exact threat.

Move the json.JSONDecodeError clause first so it actually catches.
Audited the rest of serve.py's exception handlers for the same
narrower-after-broader ordering bug; found no other instance.

Fixes Graphify-Labs#2005.

@Job28703 Job28703 left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Independently reproduced the fail-then-pass: checked out v8 base (unfixed) with the new test applied — test_load_graph_corrupted_json_prints_recovery_message fails exactly as expected (bare JSONDecodeError message instead of the recovery hint), confirming json.JSONDecodeError is indeed swallowed by the broader (ValueError, FileNotFoundError) clause ahead of it. With the reorder applied, the same test passes (6 passed on test_serve.py -k load_graph). Also spot-checked the rest of serve.py's ~20 except clauses — no other narrower-after-broader ordering issue. Clean, well-scoped fix. Thanks!

@HerenderKumar HerenderKumar left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Came here from #2005 — I had claimed it on the issue a few hours before this PR went up and had the same fix built locally, so I can vouch for the approach: json.JSONDecodeError subclasses ValueError, so moving its clause first is exactly right. I ran the same change against the full serve suites locally (117 passed, 1 skipped).

One suggestion: a small guard test asserting that a non-decode ValueError (e.g. a non-.json path) still prints the generic error: ... message rather than the corrupted-graph hint — it pins the clause order so a future refactor can't "simplify" it back:

def test_load_graph_generic_value_error_message_unchanged(tmp_path, capsys):
    p = tmp_path / "graph.txt"
    p.write_text("not a graph")
    with pytest.raises(SystemExit):
        _load_graph(str(p))
    err = capsys.readouterr().err
    assert "must be a .json file" in err
    assert "corrupted" not in err

LGTM either way.

…ession

Per review on Graphify-Labs#2017 (thanks @HerenderKumar): add a guard asserting a
non-decode ValueError (e.g. a non-.json path) still prints the plain
"must be a .json file" message, not the corrupted-graph hint. Locks in
the except-clause order from the parent fix so a future refactor can't
silently collapse the two branches back together.
@kimdzhekhon

Copy link
Copy Markdown
Author

Good catch — added that exact guard test. Thanks for vouching for the approach and for validating against the full serve suite.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

serve.py: the "graph.json is corrupted" recovery message can never be printed (except-clause ordering)

3 participants