Skip to content

OpenAI Chat Completions ignores the refusal field #46

Description

@dajiaohuang

Summary

OpenAI Chat Completions responses that report a refusal in message.refusal can be treated as malformed output instead of a provider-declared refusal.

Reproduction

A Chat Completions response with finish_reason set to stop, message.content set to null, and message.refusal set to a refusal string passes through the shared result handler. The handler checks finish_reason, then returns message.content or an empty string; it does not inspect message.refusal. A minimal in-memory response reproduced an empty ProviderResult text without raising TypeSafeError.

Expected behavior

Raise TypeSafeError that identifies the refusal and preserve the response trace, without spending a malformed-output corrective retry.

Actual behavior

The refusal is reduced to empty text and enters malformed JSON validation. With corrective retries enabled, the adapter can retry a response the provider has already identified as a refusal; without retries, the caller receives a validation error rather than a refusal error.

Related coverage

Issue #43 handles Anthropic and OpenAI Responses refusals. Its description leaves Chat Completions aside because #38 covers finish_reason. Issue #38 rejects non-success finish reasons, but this response has finish_reason=stop and the refusal is in message.refusal, so the cases are distinct.

A focused regression should cover sync and async Chat Completions responses with message.refusal, including the no-corrective-retry behavior.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions