Skip to content

gpt-5.4-mini fails via /chat/completions in strict AWF mode #32197

@hermanho

Description

@hermanho

Summary

A workflow with engine.id: copilot fail with gpt-5.4-mini reporting /chat/completions endpoint incompaibility in strict AWF mode.

The affected gh-aw workflow uses:

  • engine.id: copilot
  • model: gpt-5.4-mini
  • strict mode
  • default AWF sandbox

fails at runtime with:

400 model "gpt-5.4-mini" is not accessible via the /chat/completions endpoint

The failure appears to come from a gap between gh-aw and gh-aw-firewall:

  • gh-aw injects a dummy COPILOT_API_KEY to trigger Copilot BYOK runtime behavior.
  • gh-aw-firewall only sets COPILOT_PROVIDER_WIRE_API=responses inside the config.copilotApikey branch.
  • the Copilot provider still prefers COPILOT_GITHUB_TOKEN over COPILOT_API_KEY

This seems to leave the workflow in a mixed mode where GPT-5-family models can still end up on the default completions path.

Expected behavior

The workflow should not have error when run with gpt-5.4-mini model.

Actual behavior

The workflow compiles and starts normally, but throw the following error:

400 model "gpt-5.4-mini" is not accessible via the /chat/completions endpoint

Relevant code

gh-aw injects dummy COPILOT_API_KEY for Copilot workf1ows under AWF

if sandboxEnabled {
  env["COPILOT_API_KEY"] = constants.CopilotBYOKDummyAPIKey
  env["AWF_REFLECT_ENABLED"] = "1"
}

gh-aw-firewall only enables responses in the config.copilotApikey branch

function requiresResponsesWireApi(copilotModel: string): boolean {
  return RESPONSES_WIRE_API_MODEL_PATTERN.test(copilotModel);
}
if (config.copilotApiKey) {
    // Enable Copilot CLI offline + BYOK mode so it skips the GitHub OAuth handshake
    // and talks directly to the sidecar without needing GitHub authentication for inference.
    // Reference: https://github.blog/changelog/2026-04-07-copilot-cli-now-supports-byok-and-local-models/
    agentEnvAdditions.COPILOT_OFFLINE = 'true';
    logger.debug('COPILOT_OFFLINE set to true for offline+BYOK mode');

    // Point Copilot CLI's BYOK provider URL at the sidecar, which injects the real API key
    // and forwards the request through Squid. This is the new canonical BYOK env var.
    agentEnvAdditions.COPILOT_PROVIDER_BASE_URL = `http://${networkConfig.proxyIp}:${API_PROXY_PORTS.COPILOT}`;
    logger.debug(`COPILOT_PROVIDER_BASE_URL set to sidecar at http://${networkConfig.proxyIp}:${API_PROXY_PORTS.COPILOT}`);

    // COPILOT_PROVIDER_API_KEY placeholder: real key is held by the sidecar, never exposed to agent.
    // Set early placeholder (before this block) already handled above.
    logger.debug('COPILOT_PROVIDER_API_KEY placeholder set for credential isolation');

    const copilotModel = getCopilotModel(config);
    if (copilotModel && requiresResponsesWireApi(copilotModel)) {
      agentEnvAdditions.COPILOT_PROVIDER_WIRE_API = 'responses';
      logger.debug(`COPILOT_PROVIDER_WIRE_API set to responses for model: ${copilotModel}`);
    }
  }

gh-aw-firewall still prefers COPILOT_GITHUB_TOKEN over COPILOT_API_KEY

function resolveCopilotAuthToken(env = process.env) {
  return stripBearerPrefix(env.COPILOT_GITHUB_TOKEN) || stripBearerPrefix(env.COPILOT_API_KEY);
}

Relevant docs

The docs state that completions is the default wire API and responses is the GPT-5 override:

| `COPILOT_PROVIDER_WIRE_API` | Optional | Wire API variant: `completions` (default) or `responses` (for GPT-5 series) |

Why this looks inconsistent

  1. gh-aw injects “COPILOT_API_KEY to trigger BYOK-related runtime behavior.
  2. gh-aw-firewall only sets COPILOT_PROVIDER_WIRE_API=responses in the copilotApikey path.
  3. gh-aw-firewall still resolves auth with COPILOT_GITHUB_TOKEN first when both are present.
  4. GPT-5-family models can then still behave as though they are on the default completions path.

Reproduction

A workflow with:

engine:
  id: copilot
  model: gpt-5.4-mini
strict: true

running under the default AWF sandbox fails at runtime with:

400 model "gpt-5.4-mini" is not accessible via the /chat/completions endpoint

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions