Skip to content

fix: allow null usage in ChatStreamChunk schema for streaming responses#220

Closed
robert-j-y wants to merge 1 commit intomainfrom
devin/1775514540-issue-452-streaming-usage-null
Closed

fix: allow null usage in ChatStreamChunk schema for streaming responses#220
robert-j-y wants to merge 1 commit intomainfrom
devin/1775514540-issue-452-streaming-usage-null

Conversation

@robert-j-y
Copy link
Copy Markdown
Collaborator

Summary

The ChatStreamChunk Zod schema rejected usage: null in streaming chat completion chunks, causing a ZodError (invalid_type: expected object, received null) that prevented consuming streams entirely. The API sends usage: null in intermediate streaming chunks before final usage data is available.

Fix: Changed usage from .optional() to .nullable().optional() in both the OpenAPI spec and the generated schema, so it now accepts null | undefined | ChatUsage.

The Responses API path (OpenResponsesResult) already handled usage: null correctly — only the Chat Completions streaming path was affected.

Fixes OpenRouterTeam/ai-sdk-provider#452 (moved from #146)

Review & Testing Checklist for Human

  • Verify the OpenAPI spec change (allOf + nullable: true pattern) will produce the correct output when Speakeasy regenerates — this is the standard OpenAPI 3.0 nullable-ref pattern, but confirm it matches what Speakeasy expects
  • Confirm no downstream SDK consumers rely on usage being strictly ChatUsage | undefined (never null) — e.g., code doing === undefined checks instead of falsy checks

Notes

  • The generated file (src/models/chatstreamchunk.ts) was edited directly alongside the OpenAPI spec. Speakeasy's persistent edits mechanism should preserve this via 3-way merge on regeneration.
  • The Responses API StreamEvents schema already accepted usage: null (confirmed by test) — this was only broken on the Chat Completions streaming path.

Link to Devin session: https://app.devin.ai/sessions/e3b2cbc5fbfe4b7499f581cb30795525
Requested by: @robert-j-y

The ChatStreamChunk Zod schema only accepted usage as optional (undefined),
but the API sends usage: null in streaming chat completion chunks and
response.created events. This caused a ZodError (invalid_type: expected
object, received null) that prevented consuming streams entirely.

Changes:
- OpenAPI spec: add nullable: true to ChatStreamChunk.usage field
- Generated schema: change usage from .optional() to .nullable().optional()
- TypeScript type: update ChatUsage union to include null
- Add regression test covering null, undefined, and valid usage scenarios

Fixes OpenRouterTeam/ai-sdk-provider#452
(Moved from #146)

Co-Authored-By: Robert Yeakel <robert.yeakel@openrouter.ai>
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.

Streaming Responses API fails Zod validation - usage field is null instead of object/undefined

2 participants