Skip to content

[Bug] azure-openai does not recover invalid_encrypted_content after a provider switch #5583

Description

@lubc

Client or integration

Codex App

Area

Provider adapter

Summary

Switching an existing Responses thread to an azure-openai provider can return invalid_encrypted_content. The thread contains a reasoning item encrypted by the previous provider, and Azure cannot verify it.

OpenCodex already has one-shot opaque-blob recovery for this exact error shape. However, both recovery gates require adapterName === "openai-responses". The Azure adapter wraps the same Responses passthrough contract but reports adapterName === "azure-openai", so recovery never runs.

I expected OpenCodex to remove the foreign reasoning state and retry once, matching the behavior added for OpenAI in #2269.

Reproduction

  1. Configure a key-auth provider with adapter: "azure-openai" and a Responses-capable Azure model.
  2. Start a thread on another Responses provider, then switch the same thread to the Azure model.
  3. The next request may replay the previous provider's reasoning encrypted_content.
  4. Azure returns 400 invalid_encrypted_content.

The failure is also deterministic with a direct request containing an undecryptable reasoning item:

curl -sS http://127.0.0.1:10100/v1/responses \
  -H 'Content-Type: application/json' \
  -d '{
    "model": "azure-test/gpt-5.6-sol",
    "input": [
      {
        "type": "reasoning",
        "id": "rs_probe",
        "summary": [],
        "encrypted_content": "gAAAAABprobe"
      },
      {
        "type": "message",
        "role": "user",
        "content": [{"type": "input_text", "text": "Reply with exactly OK."}]
      }
    ],
    "reasoning": {"effort": "high"},
    "max_output_tokens": 64,
    "stream": false
  }'

Current result: one upstream request and the Azure 400 reaches the client.

I validated a local fix in two parts:

  1. Allow azure-openai in both adapter gates in src/server/responses/core-opaque-recovery.ts.
  2. When _stripReasoningEncryptedContent is set for an Azure destination, drop the stale reasoning input item. Removing only encrypted_content leaves the foreign id and Azure then returns Item with id 'rs_probe' not found.

With both changes, the same request performs one recovery retry and completes with 200.

Version

2.61.0

Operating system

macOS 26.0.1 (25A362)

Provider and model

Custom azure-openai provider / gpt-5.6-sol

Logs or error output

{
  "error": {
    "message": "The encrypted content gAAA... could not be verified. Reason: Encrypted content could not be decrypted or parsed.",
    "type": "invalid_request_error",
    "param": null,
    "code": "invalid_encrypted_content"
  }
}

Screenshots and supporting files

Related but not Azure-specific: #2247, #2248, #2251, and merged fix #2269.

Current dev still limits opaque-blob recovery to openai-responses in core-opaque-recovery.ts.

Redacted configuration

{
  "providers": {
    "azure-test": {
      "adapter": "azure-openai",
      "baseUrl": "https://<redacted>/openai/v1",
      "authMode": "key",
      "apiKey": "${AZURE_API_KEY}",
      "models": ["gpt-5.6-sol"]
    }
  }
}

Checks

  • I searched existing issues and documentation.
  • I removed secrets, tokens, account details, request credentials, and personal data.

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

    bugSomething isn't workingproviderProvider adapters, OpenAI-compat presets, upstream API quirks

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions