Skip to content

fix(mcp): return -32600 Invalid Request on non-object JSON payloads (closes #22) - #32

Merged
tonydzi merged 1 commit into
tonydzi:mainfrom
Kaap10:fix-mcp-non-object-json
Oct 19, 2026
Merged

tonydzi merged 1 commit into
tonydzi:mainfrom
Kaap10:fix-mcp-non-object-json

Conversation

@Kaap10

@Kaap10 Kaap10 commented Oct 19, 2026

Copy link
Copy Markdown
Collaborator

Summary

Closes #22 by ensuring that non-object JSON payloads (e.g. lists, bare literals) return a structured JSON-RPC -32600 Invalid Request response rather than raising an unhandled AttributeError and terminating the stdio loop.

Changes Made

  • src/sqlite_graph_memory/mcp_server.py:
    • Added an explicit isinstance(req, dict) type check at the beginning of handle_request().
    • Returns {"jsonrpc": "2.0", "id": None, "error": {"code": -32600, "message": "Invalid Request: expected JSON object"}} when the request payload is not a JSON object.
    • The stdio loop in main() serializes and flushes this error response to stdout and continues reading subsequent requests instead of crashing.
  • tests/test_mcp_server.py:
    • Added test_handle_request_non_object_json: directly tests handle_request with list ([1, 2, 3]), string literal ("literal_string"), number (123), and boolean (True).
    • Added test_stdio_loop_handles_non_object_json_and_continues: feeds an array ([1, 2, 3]), a bare string literal ("bare literal"), and a valid request (ping) into simulated stdio, verifying that both invalid payloads receive -32600 and the valid request receives {} result without terminating the loop.

1. Red Run (Before Fix on main)

Running the regression tests before the fix raises AttributeError:

================================== FAILURES ===================================
_____________________ test_handle_request_non_object_json _____________________

    def test_handle_request_non_object_json():
        for payload in ([1, 2, 3], "literal_string", 123, True):
>           resp = handle_request(payload)

req = [1, 2, 3]

    def handle_request(req: dict) -> dict:
>       method = req.get("method")
E       AttributeError: 'list' object has no attribute 'get'

src/sqlite_graph_memory/mcp_server.py:159: AttributeError
=========================== short test summary info ===========================
FAILED tests/test_mcp_server.py::test_handle_request_non_object_json - AttributeError: 'list' object has no attribute 'get'
FAILED tests/test_mcp_server.py::test_stdio_loop_handles_non_object_json_and_continues
====================== 2 failed, 15 deselected in 1.01s =======================

2. Green Run (After Fix)

Running the test suite turns GREEN:

tests/test_mcp_server.py .................                               [100%]
17 passed in 1.61s

Full repository suite: 96 passed.


3. Manual Pipe Verification

"[1, 2, 3]`n`"bare literal`"`n42`n{`"jsonrpc`": `"2.0`", `"id`": 1, `"method`": `"ping`"}" | python src/sqlite_graph_memory/mcp_server.py

Output:

{"jsonrpc": "2.0", "id": null, "error": {"code": -32600, "message": "Invalid Request: expected JSON object"}}
{"jsonrpc": "2.0", "id": null, "error": {"code": -32600, "message": "Invalid Request: expected JSON object"}}
{"jsonrpc": "2.0", "id": null, "error": {"code": -32600, "message": "Invalid Request: expected JSON object"}}
{"jsonrpc": "2.0", "id": 1, "result": {}}

AI Disclosure

Code and tests generated with AI assistance (Antigravity / Gemini) and verified locally with Red -> Green test execution.

@Kaap10

Kaap10 commented Oct 19, 2026

Copy link
Copy Markdown
Collaborator Author

Adds the -32600 Invalid Request type guard to keep the stdio loop running when non-object JSON payloads (arrays/literals) arrive.
Includes unit tests verifying both direct payload handling and uninterrupted stdio loop continuation. Ready for review!

@tonydzi

tonydzi commented Oct 19, 2026

Copy link
Copy Markdown
Owner

Mycroft speaking, the synthetic AI co-founder at Palo Alto AI Research Lab. No pulse, but a working diff reader.

Logged your pull request ("fix(mcp): return -32600 Invalid Request on non-object JSON payloads (closes #22)") after 2 h of silence, which is on us. What a machine can already tell: 2 file(s) touched, +56/-1, CI green. A human from the lab reads it within 48 hours, as CONTRIBUTING.md promises; if that clock runs out, ping the thread, it is not rude.

— TonyDzi / Palo Alto AI Research Lab · this repo is one shelf of a bigger workshop (second brain, agent-fleet consensus, verification gates): github.com/tonydzi

@tonydzi tonydzi left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

@Kaap10 reviewed as promised on #22.

  • On the PR head (mcp_server.py +9, tests +48) pytest tests gives 96 passed.
  • Red proof: your two new tests (test_handle_request_non_object_json, test_stdio_loop_handles_non_object_json_and_continues) fail against main's mcp_server.py with the AttributeError from the issue, so they pin the bug.
  • id: null with -32600 is what JSON-RPC 2.0 prescribes for a request that cannot be parsed into an object. Good.

One note, not a blocker: a JSON array is technically a batch in JSON-RPC 2.0, and the guard answers it with Invalid Request. That is right for this server since it does not advertise batch support, but the message could say so. Happy to take it as a follow-up.

Approving and merging. Note that #33 touches the same test file and will need a rebase after this lands.

@tonydzi
tonydzi merged commit cf3c90a into tonydzi:main Oct 19, 2026
8 checks passed
tonydzi added a commit that referenced this pull request Oct 27, 2026
…ing credits

CONTRIBUTING promised outside contributors a CHANGELOG line; nothing checked it and four merges
since 19.10 were unnamed (#32, #33, #35, #57). scripts/credit_gate.py now fails CI on a merged
outside PR without a changelog paragraph holding @handle and #number, and on any @handle that is
not a real GitHub user.

Assisted-by: Claude Code/claude-sonnet-5-5
Machine: MacPro192
Account: tonydzi
Operator: Anton
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.

MCP server: unhandled non-object JSON crashes stdio loop with AttributeError

2 participants