Skip to content

fix(registry/client): surface malformed and non-string error responses (PILOT-132)#10

Open
matthew-pilot wants to merge 1 commit into
mainfrom
openclaw/pilot-132-20260530-090839
Open

fix(registry/client): surface malformed and non-string error responses (PILOT-132)#10
matthew-pilot wants to merge 1 commit into
mainfrom
openclaw/pilot-132-20260530-090839

Conversation

@matthew-pilot
Copy link
Copy Markdown
Collaborator

What

The registry client's sendOnEntry, sendLocked, and sendJSONLocked treated any valid-JSON response without an "error" key as success, silently accepting garbage responses. Additionally, only string-typed error values were detected — numeric or object error values were silently swallowed.

Fix

Two changes in each of the three send functions:

  1. Broaden error detectionresp["error"].(string)resp["error"] with %v formatting, so any error value type (string, int, object) is surfaced.
  2. Add type-envelope validation — if a non-empty response lacks both "error" and "type" keys, it is rejected as malformed. Empty responses remain valid (backward-compatible).

The rendezvous server always includes a "type" field in its responses, so this check is a safe defense-in-depth measure.

Verification

  • go build ./... — ✅ clean
  • go vet ./... — ✅ clean
  • go test ./registry/client/ -count=1 -timeout 60s — ✅ all tests pass (including new TestSendOnEntryReturnsErrorOnNonStringError and TestSendReturnsErrorOnMalformedResponse)

Diff stat

 registry/client/binary_client.go         |  8 +++--
 registry/client/client.go                | 16 +++++++---
 registry/client/zz_client_branch_test.go | 51 ++++++++++++++++++++++++++++++++
 3 files changed, 69 insertions(+), 6 deletions(-)

Closes PILOT-132

…s (PILOT-132)

The registry client's sendOnEntry, sendLocked, and sendJSONLocked
treated any valid-JSON response without an "error" key as success,
silently accepting garbage (e.g. {"unexpected":"key"}). Additionally,
only string-typed error values were detected — numeric or object
error values (e.g. {"error":403}) were silently swallowed.

Two changes in each of the three send functions:

1. Broaden error detection to handle any error value type
   (resp["error"].(string) → resp["error"] with %v formatting).

2. Add a "type" envelope field check: if a non-empty response lacks
   both "error" and "type", it is rejected as malformed. Empty
   responses remain valid to preserve backward compatibility with
   any edge case.

The rendezvous server always includes a "type" field in its
responses, so this check is a safe defense-in-depth measure.

Closes PILOT-132
@matthew-pilot matthew-pilot added the matthew-fix-larger Medium-scope fix (≤10 files, ≤200 LoC) — operator review with diff stat label May 30, 2026
@codecov
Copy link
Copy Markdown

codecov Bot commented May 30, 2026

Codecov Report

❌ Patch coverage is 66.66667% with 4 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
registry/client/binary_client.go 50.00% 1 Missing and 1 partial ⚠️
registry/client/client.go 75.00% 1 Missing and 1 partial ⚠️

📢 Thoughts on this report? Let us know!

@matthew-pilot
Copy link
Copy Markdown
Collaborator Author

🛠️ Matthew PR Worker — Status (pilot-protocol/common#10)

State: OPEN · MERGEABLE ✅
CI: just created (Codecov patch: 66.67%, missing 4 lines)
Canary: N/A — common has artifact:none, not applicable
Jira: PILOT-132 — re-evaluation (prior PR #147 closed for backward-compat concerns)
Last operator activity: TeoSlayer — last commit 2026-05-29T21:01Z (~12h ago)

🛠️ auto-status by matthew-pr-worker

@matthew-pilot
Copy link
Copy Markdown
Collaborator Author

🛠️ Matthew Explains — pilot-protocol/common#10

What this does

Hardens the registry client response parser in three send paths (sendOnEntry, sendLocked, sendJSONLocked) with two changes:

  1. Broadens error detection from resp["error"].(string) to resp["error"] (any type)
  2. Adds type-envelope validation — non-empty responses without a "type" key are rejected

File-by-file walkthrough

registry/client/binary_client.go:274-279sendJSONLocked: replaces . (string) type assertion on resp["error"] with untyped %v formatting, so numeric/object errors are surfaced. Adds the "type"-key presence check after error handling.

registry/client/client.go:445-450sendOnEntry: same two changes — broadened error detection + type-envelope guard. This is the hottest path (used on every pooled-connection round-trip).

registry/client/client.go:521-526sendLocked: same two changes. This covers the TLS-on-new-connection path.

registry/client/zz_client_branch_test.go:419-466 — Two new tests:

  • TestSendOnEntryReturnsErrorOnNonStringError (L419-438): fake server returns {"error": 403} (float64), verifies the error is surfaced with the numeric value
  • TestSendReturnsErrorOnMalformedResponse (L440-465): fake server returns {"unexpected":"key"}, verifies the "malformed response" error is raised

Why

The old code silently accepted any valid-JSON response that lacked an "error".(string) field — even garbage. The rendezvous server always includes a "type" envelope key, so requiring it is a safe protocol invariant check. The previous attempt (PR #147 in TeoSlayer/pilotprotocol) was closed for backward-compat concerns; this version is narrower in scope (common/registry/client only) and preserves empty-response compatibility.

Impact

  • Wire format: none — valid rendezvous responses already include "type"
  • API: transparent — callers already check for errors
  • Risk: low — two new targeted tests, all existing tests pass

@matthew-pilot
Copy link
Copy Markdown
Collaborator Author

Matthew PR Status — #10

Title: fix(registry/client): surface malformed and non-string error responses (PILOT-132)
Status: OPEN | Mergeable: MERGEABLE
Author: @matthew-pilot (matthew-pilot bot)
Created: 2026-05-30T09:10:20Z
Branch: openclaw/pilot-132-20260530-090839 -> main
Changes: +69/-6 across 3 files

Tickets

Labels

matthew-fix-larger

Files Changed

  • registry/client/binary_client.go (+6/-2)
  • registry/client/client.go (+12/-4)
  • registry/client/zz_client_branch_test.go (+51/-0)

Next Actions

  • Explain: command /pr explain #10 — detailed analysis
  • Canary retry: command /pr retry-canary #10 (if CI failed)
  • Fix & update: command /pr fix #10 <instructions>
  • Rebase: command /pr rebase #10
  • Close: command /pr close #10 <reason>

Auto-generated status check by matthew-pr-worker

@matthew-pilot
Copy link
Copy Markdown
Collaborator Author

Matthew PR Explain — #10

What this PR does

fix(registry/client): surface malformed and non-string error responses (PILOT-132)

Scope

  • Files: 3 files
  • Delta: +69/-6 lines
  • Labels: matthew-fix-larger
  • Mergeable: MERGEABLE

Tickets

Files

  • registry/client/binary_client.go (+6/-2)
  • registry/client/client.go (+12/-4)
  • registry/client/zz_client_branch_test.go (+51/-0)

Review Notes

  • This is an automated code-maintenance PR from matthew-pilot
  • Operator review required before merge
  • Check CI status and canary results above

Auto-generated explain by matthew-pr-worker

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

Labels

matthew-fix-larger Medium-scope fix (≤10 files, ≤200 LoC) — operator review with diff stat

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant