Skip to content

Fix event ingress dropping real broker events: accept null optional fields - #220

Merged
willwashburn merged 1 commit into
mainfrom
fix/event-schema-nullable-fields
Jun 10, 2026
Merged

Fix event ingress dropping real broker events: accept null optional fields#220
willwashburn merged 1 commit into
mainfrom
fix/event-schema-nullable-fields

Conversation

@willwashburn

Copy link
Copy Markdown
Member

Bug

The broker serializes absent optional fields as null; the #214 ingress schemas used .optional() (accepts missing, rejects null), so real events were dropped at ingressagent_spawned, worker_ready, and critically relay_inbound (chat messages). Observed live:

[broker] Dropped malformed broker event: { kind: 'relay_inbound',
reason: 'thread_id: Expected string, received null' }

(The throttled malformed-event telemetry from #195/#214 is what surfaced this.)

Fix

All 30 optional scalar fields in src/shared/schemas/broker-events.ts.nullish() (accepts null and undefined; still rejects wrong non-null types). The three z.unknown().optional() fields already accepted null. This restores pre-#214 behavior, where null-bearing events flowed through untouched.

Why tests missed it

Fixtures were derived from the SDK's TypeScript declaration (provider?: string) — TS optionality says nothing about JSON null on the wire. New regression tests pin the exact three dropped payloads from production logs, plus a wrong-type case proving validation still rejects garbage.

Verification

  • npx vitest run src/main/broker.test.ts → 76/76 (4 new)
  • npx vitest run → 349/349 · npm run typecheck ✓ both configs · npm run lint ✓ 0 errors

🤖 Generated with Claude Code

The live broker serializes unset optional fields as JSON null, not
omitted keys. The ingress schemas (#214) used .optional(), which
accepts undefined but rejects null, so real agent_spawned,
worker_ready, and relay_inbound events were dropped at ingress —
including chat messages. Observed in production logs:
[broker] Dropped malformed broker event: { kind: 'relay_inbound',
reason: 'thread_id: Expected string, received null' }
All optional scalar fields are now .nullish(). Regression tests pin
the exact dropped payloads; wrong non-null types are still rejected.
The #214 test gap: fixtures were built from the SDK's TypeScript
declaration (provider?: string), which says nothing about wire-level
null.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@coderabbitai

Copy link
Copy Markdown

Warning

Review limit reached

@willwashburn, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 8 minutes and 55 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 8140d82c-160b-4d3f-9cec-b02b4ff1a353

📥 Commits

Reviewing files that changed from the base of the PR and between 2023bac and d15ba63.

📒 Files selected for processing (2)
  • src/main/broker.test.ts
  • src/shared/schemas/broker-events.ts
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/event-schema-nullable-fields

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@gemini-code-assist

Copy link
Copy Markdown

Warning

You have reached your daily quota limit. Please wait up to 24 hours and I will start processing your requests again!

@willwashburn
willwashburn merged commit f98c6bb into mainJun 10, 2026
5 checks passed
@willwashburn
willwashburn deleted the fix/event-schema-nullable-fields branch June 10, 2026 16:30
@miyaontherelaymiyaontherelay added the factory:in-progress Factory agents are working on this issue. label Aug 25, 2026
@miyaontherelay

Copy link
Copy Markdown
Contributor

Factory dispatch for 220
Implementers: ar-220-impl-pear
Reviewer: ar-220-review-pear

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

Labels

factory:in-progressFactory agents are working on this issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@willwashburn@miyaontherelay