Skip to content

Harden JSON-RPC 2.0 message handling - #7

Open
minrbook wants to merge 6 commits into
jershell:masterfrom
minrbook:agent/suppress-notification-error-responses
Open

Harden JSON-RPC 2.0 message handling#7
minrbook wants to merge 6 commits into
jershell:masterfrom
minrbook:agent/suppress-notification-error-responses

Conversation

@minrbook

@minrbook minrbook commented Jul 30, 2026

Copy link
Copy Markdown

Summary

  • never respond to failed notifications, including unknown methods, invalid parameters, synchronous exceptions, and rejected promises
  • release pending calls after error responses instead of retaining their deferred closures
  • validate JSON-RPC 2.0 request and response structure before dispatching or settling calls
  • preserve request ID value and type when correlating responses
  • safely handle overridden object properties and prototype-sensitive method names
  • return Invalid Request for primitive messages and empty batches
  • keep the minified browser build ES5-compatible and test it against the source build

Why

Several error paths did not follow JSON-RPC 2.0 semantics. Notifications could produce error responses, rejected calls remained in waitingframe for the lifetime of a connection, and malformed messages could be executed or settle unrelated pending calls.

The updated resolver validates the message shape before classifying it, uses safe own-property checks, and stores pending calls under typed keys. Invalid responses are ignored without settling their matching call, while valid success and error responses both release their pending slot.

Validation

  • 50 Mocha tests passing
  • source and minified builds produce matching protocol behavior
  • regression coverage for notification failures, mixed batches, request cleanup, invalid request fields, malformed responses, ID type mismatches, overridden hasOwnProperty, and empty batches
  • generated distribution remains ES5 syntax and contains no arrow functions

Thank you for creating and maintaining this lightweight JSON-RPC library. I hope these protocol-compliance and reliability improvements are useful to the project.

jiangchen added 6 commits July 30, 2026 14:21
Success paths already deleted the deferred after resolve, but error
responses only rejected the Promise and left the slot in place. On a
long-lived WebSocket each failed call retained resolve/reject closures
indefinitely. Delete the entry after reject, matching resolve, and add a
regression test.
Reject non-2.0 jsonrpc, non-string methods, and non-structured params
with -32600. Surface Invalid Request for top-level null/primitives
instead of silently dropping them. Require responses to carry exactly
one of result or error, and match pending call ids by value and type
via Map (number 1 !== string "1"). Update batch response fixtures and
add protocol regression tests.
Reject non-object error payloads and errors without an integer code
or string message without settling or freeing waiting calls. Use
Object.prototype.hasOwnProperty.call for all property checks so
inputs cannot override hasOwnProperty. Store pending ids with a
typeof-prefixed key on an Object.create(null) map so number/string
ids never collide without depending on Map. Always report Invalid
Request with id null. Rebuild minified dist with compress.arrows
disabled to keep ES5-compatible output for older browsers.
Require response id to be a string, number, or null via
isValidRequestId so boolean/object/array ids are treated as invalid
responses and never settle pending calls. Return a single Invalid
Request (id null) for empty batch arrays per JSON-RPC 2.0. Centralize
console.log capture/restore in tests so failed assertions cannot leave
a patched logger for later cases.
@minrbook minrbook changed the title Do not respond to failed notifications Harden JSON-RPC 2.0 message handling Jul 30, 2026
@minrbook
minrbook marked this pull request as ready for review July 30, 2026 08:11
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.

1 participant