Skip to content

Set ErrorCode Refusal on non-streaming Chat Completions refusals to match the Responses path - #654

Merged
George Adams (gdams) merged 1 commit into
microsoft:mainfrom
PratikDhanaveFork:chat-refusal-errorcode
Jul 29, 2026
Merged

Set ErrorCode Refusal on non-streaming Chat Completions refusals to match the Responses path#654
George Adams (gdams) merged 1 commit into
microsoft:mainfrom
PratikDhanaveFork:chat-refusal-errorcode

Conversation

@PratikDhanave

Copy link
Copy Markdown
Contributor

What

The non-streaming Chat Completions path maps a model refusal to a message.ErrorContent but leaves ErrorCode empty:

contents = append(contents, &message.ErrorContent{Message: choice.Message.Refusal})

Every Responses-path refusal (three sites in responses.go) tags ErrorCode: "Refusal". This change adds the same tag on the Chat Completions non-streaming path.

Why

Refusals should be categorizable the same way regardless of which OpenAI surface produced them. Today a consumer routing on ErrorContent.ErrorCode classifies Responses refusals but silently drops identical Chat Completions refusals into the empty-code bucket. This mirrors the .NET/Python SDKs, where refusal content carries a consistent, well-known code across the chat and responses clients, and aligns with the existing "Refusal" convention already asserted in responses_test.go.

Not a duplicate of #556, which concerns the streaming chat refusal path.

Testing

Added TestChatResponseWithRefusalContent_ParsesCorrectly in chat_test.go (mirroring TestResponsesResponseWithRefusalContent_ParsesCorrectly): it returns a chat completion with content: null and a refusal string, runs the agent, extracts the *message.ErrorContent, and asserts both Message and ErrorCode == "Refusal". The test fails before the fix (empty ErrorCode) and passes after. go build ./..., go vet, and go test ./provider/openaiprovider/... all pass.

@PratikDhanave
PratikDhanave (PratikDhanave) requested a review from a team as a code owner July 23, 2026 07:55
Copilot AI review requested due to automatic review settings July 23, 2026 07:55

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Aligns refusal handling in the non-streaming Chat Completions provider with the Responses provider by consistently tagging refusal-derived message.ErrorContent with ErrorCode: "Refusal", enabling uniform downstream classification.

Changes:

  • Set ErrorCode: "Refusal" when mapping choice.Message.Refusal into *message.ErrorContent on the non-streaming chat path.
  • Add a regression test to ensure refusals with content: null are parsed into ErrorContent with both Message and ErrorCode populated.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
provider/openaiprovider/chat.go Tags non-streaming chat refusal ErrorContent with ErrorCode: "Refusal" to match Responses behavior.
provider/openaiprovider/chat_test.go Adds a test asserting refusal responses produce ErrorContent with ErrorCode == "Refusal".

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@github-actions

This comment has been minimized.

@github-actions github-actions Bot added the parity-approved Go API consistency review found no parity issues label Jul 23, 2026
@github-actions

This comment has been minimized.

@github-actions

Copy link
Copy Markdown
Contributor

Parity Review — ✅ Approved

This PR sets ErrorCode: "Refusal" on the non-streaming Chat Completions refusal path to match the Responses path. No exported Go APIs were added or changed.

Cross-repo consistency: The PR description correctly notes that .NET and Python SDKs carry a consistent, well-known code for refusal content across both chat and responses surfaces. The Go change aligns with that convention.

Within-repo consistency: responses.go already sets ErrorCode: "Refusal" at all three refusal sites. This PR closes the gap on the non-streaming chat path.

Out of scope for this PR: The streaming chat refusal path (chat.go line 178) still does not set ErrorCode; that is tracked separately in #556 and is pre-existing — not introduced here.

No new exported identifiers were added or changed, so the public-api-change label is not warranted. The existing parity-approved label is correct.

Warning

Firewall blocked 1 domain

The following domain was blocked by the firewall during workflow execution:

  • awmgmcpg

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "awmgmcpg"

See Network Configuration for more information.

Generated by Go API Consistency Review Agent · 34.3 AIC · ⌖ 3.95 AIC · ⊞ 5.9K ·

The non-streaming Chat Completions path emitted an ErrorContent for a
model refusal without setting ErrorCode, while every Responses-path
refusal tags ErrorCode "Refusal". Tag the Chat Completions refusal the
same way so consumers categorizing by ErrorContent.ErrorCode classify
identical refusals consistently across both providers.
@gdams
George Adams (gdams) added this pull request to the merge queue Jul 29, 2026
Merged via the queue into microsoft:main with commit 1544de6 Jul 29, 2026
20 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

parity-approved Go API consistency review found no parity issues

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants