Skip to content

Codex Desktop macOS: Azure gpt-5.6-sol automations fail because bootstrap output has no call_id #41799

Open

Description

@SyntaxFear

Summary

On macOS, Codex Desktop cron automations using an Azure/OpenAI-compatible Responses provider and gpt-5.6-sol fail before the saved prompt reaches the model.

The app-server starts the automation turn by injecting a standalone function_call_output for codex_app/automation_update with both id: None and call_id: None. Azure rejects the Responses request with HTTP 400:

Invalid Value: 'input.call_id'. Function call output requires call_id.

This is related to #41690, but this reproduction is on macOS with Azure and affects multiple unrelated production automations, not only the reported Windows/DeepSeek configuration.

Environment

  • Codex Desktop: 26.825.51511 (build 7377)
  • Bundled Codex CLI/app-server: 0.151.0-alpha.7.2
  • OS: macOS 26.6.2, Apple Silicon
  • Model: gpt-5.6-sol
  • Provider: Azure OpenAI-compatible endpoint (hostname redacted)
  • Provider auth: environment-variable API key
  • wire_api = "responses"
  • Automation kind: standalone local cron

The Azure API key, endpoint hostname, local username, project names, and production prompt contents are intentionally omitted.

Minimal reproduction

Create an active local automation with:

kind = "cron"
prompt = "say hi to me"
rrule = "RRULE:FREQ=MINUTELY;INTERVAL=1"
model = "gpt-5.6-sol"
execution_environment = "local"

Use a custom provider configured as:

model_provider = "azure"

[model_providers.azure]
name = "Azure"
base_url = "https://<redacted>.services.ai.azure.com/openai/v1"
env_key = "<redacted>"
wire_api = "responses"

Wait for the scheduled occurrence.

Actual result

The scheduler creates a run and thread, but the first turn fails in about two seconds. The automation prompt never reaches the model.

The local log shows the exact invalid item:

Submission ... TurnInputRequest {
  input: ResponseItem(FunctionCallOutput {
    id: None,
    call_id: None,
    name: Some("automation_update"),
    namespace: Some("codex_app"),
    output: ...
  })
}

It is immediately followed by:

Turn error: {
  "error": {
    "message": "Invalid Value: 'input.call_id'. Function call output requires call_id.",
    "type": "invalid_request_error",
    "param": "input"
  }
}

Local state after each occurrence:

  • automation remains ACTIVE
  • last_run_at and next_run_at advance
  • an automation_runs row is created
  • the run is left as PENDING_REVIEW
  • the created thread has systemError
  • no assistant response or automation work occurs

The same error occurs for multiple unrelated cron automations with different prompts, projects, and reasoning levels. Normal interactive gpt-5.6-sol turns through the same Azure provider succeed.

Regression evidence

  • Last known successful scheduled automation before the desktop update: 2026-08-30 14:46:55 +04
  • Codex Desktop application updated: 2026-08-30 21:32:46 +04
  • Repeated failed scheduled runs observed after the update, including from 2026-08-31 01:00:39 +04 onward

Changing the RRULE, prompt, workspace, or reasoning effort does not affect the failure.

Verified local workaround

A localhost reverse proxy was placed between Codex and the same Azure endpoint. It performs one narrowly scoped transformation:

  • find a function_call_output where name == "automation_update", namespace == "codex_app", and call_id is absent;
  • convert that orphan item into a developer message containing the same text;
  • forward all other request fields and all responses unchanged.

Results:

  1. A synthetic request containing the exact malformed bootstrap shape completed through Azure with gpt-5.6-sol.
  2. A real one-minute Codex Desktop cron automation then completed successfully and replied Hi! 👋.

This isolates the failure to the automation bootstrap serialization rather than the scheduler, model deployment, credentials, network, or automation prompt.

Expected behavior

Codex should not send a standalone function_call_output without a valid matching call_id to a strict Responses provider.

Possible fixes:

  1. Represent the automation bootstrap as a normal user/developer message.
  2. Preserve a real preceding function call and matching call_id.
  3. Add provider capability normalization before serializing TurnToolOutput into a Responses request.

At minimum, a failed automation run should be marked failed with the provider error instead of remaining PENDING_REVIEW.

Activity

  1. added
    bugSomething isn't working
    appIssues related to the Codex desktop app
    azureIssues related to the Azure-hosted OpenAI models
    app-serverIssues involving app server protocol or interfaces
    on Aug 31, 2026
  2. github-actions commented on Aug 31, 2026

    @github-actions
    Contributor

    Potential duplicates detected. Please review them and close your issue if it is a duplicate.

    Powered by Codex Action

  3. weltonrodrigo commented on Aug 31, 2026

    @weltonrodrigo

    Such bug. Much breakage. Very impactful to my workflow. Wow. Please fix. 🐕

  4. Ahmet-Dedeler commented on Aug 31, 2026

    @Ahmet-Dedeler

    Confirming this on the same build, with two things I think are new to the thread: a
    more severe failure mode than a skipped automation run, and a working proxy-level
    workaround
    .

    Same build, different host

    • Codex Desktop 26.825.51511 (build 7377)
    • Bundled app-server 0.151.0-alpha.7.2
    • macOS 27.0, Apple Silicon
    • Model gpt-5.6-sol, provider Azure OpenAI-compatible, wire_api = "responses"
    • Provider auth: az account get-access-token Bearer (not an env-var key), so the
      defect is independent of the auth mode

    Identical error text: Invalid Value: 'input.call_id'. Function call output requires call_id.

    The part that is worse than a skipped run

    Both this issue and #41690 describe an automation whose own first turn dies, leaving a
    fresh thread with systemError. That understates the blast radius when the automation has a
    target_thread_id pointing at an existing thread.

    My automation is a kind = "heartbeat" targeting a long-running thread. The orphan item is
    persisted into that thread's rollout, and because Codex replays full history on every
    request, the thread is permanently bricked from the first bad tick onward — including for
    the human. My own typed message hit the same 400 forty minutes later. The thread cannot
    recover on its own, and each subsequent tick appends another orphan.

    Forensics from the rollout (54,172 lines, 379 MB):

    function_call_output items total : 9184
            ... missing call_id      :    4
    first orphan  : line 54152, 2026-08-31T15:31:18Z
    then          : 15:46:18Z, 16:01:18Z, 16:16:18Z   (exactly the 15-min automation interval)
    

    Everything before line 54152 in that thread is healthy, so this is a clean regression boundary.

    Model-initiated calls are fine; only the injection path is broken

    Classifying every automation_update item in the same rollout:

    12 x  response_item / function_call        WITH call_id   first 2026-08-29T22:17:48Z
     4 x  response_item / function_call_output  NO call_id     first 2026-08-31T15:31:18Z
    

    When the model calls automation_update, the pairing is correct. Only the app-server's
    unsolicited heartbeat/bootstrap injection omits call_id. The persisted orphan also carries
    an internal_chat_message_metadata_passthrough key alongside id/name/namespace/output.

    Schema-normalizing proxies do not help

    #41690 links this to the root-oneOf tool-schema issues (#30132, #37786, #30523). Worth
    separating: I already run a local proxy that normalizes the automation_update tool schema
    for Azure, and it makes no difference here. That fix rewrites body.tools[]; this defect is in
    body.input[]. They are independent bugs that happen to involve the same tool.

    Workaround

    Two layers, in case they help others stuck on Azure:

    1. Un-brick an existing thread — drop the orphans from the rollout offline (app quit):

    p = payload
    if p.get("type") == "function_call_output" and not p.get("call_id"):
        continue  # drop the line

    2. Keep automations running — repair input in-flight at the proxy, rewriting an orphan
    into an equivalent user message rather than dropping it, so the heartbeat prompt still reaches
    the model:

    for (let i = 0; i < body.input.length; i++) {
      const item = body.input[i];
      if (item?.type !== 'function_call_output') continue;
      if (typeof item.call_id === 'string' && item.call_id.length > 0) continue;
      const label = `${item.namespace ? item.namespace + '/' : ''}${item.name ?? 'tool'}`;
      body.input[i] = {
        type: 'message', role: 'user',
        content: [{ type: 'input_text', text: `[${label}]\n${item.output}` }],
      };
    }

    Only items with no call_id are touched — one that carries a call_id is left alone, since
    its function_call may legitimately sit behind previous_response_id.

    Because the rewrite happens on every request, this also repairs the already-persisted orphans on
    replay, which recovers a bricked thread without editing the rollout at all.

    That second layer is arguably what the app-server should do natively: #41820 asks for exactly
    this shape — automation updates delivered as attributable messages rather than as a synthetic
    tool result with no call.

  5. Rafik-Belkadi-Reccap commented on Sep 1, 2026

    @Rafik-Belkadi-Reccap

    Same here, i feel like on every update they break azure everytime

  6. amirsalaar commented on Sep 7, 2026

    @amirsalaar

    Independent confirmation of the existing issue from another macOS Codex Desktop installation, as of 2026-09-07.

    • The same HTTP 400 occurs for scheduled tasks using an Azure/OpenAI-compatible Responses provider.
    • Reproduced with gpt-5.6-luna and gpt-5.6-terra on bundled CLI 0.151.0-alpha.7.2; the defect remains on 0.153.4.
    • The run fails immediately, before the scheduled prompt reaches the model.
    • The serialized input contains a standalone function_call_output for codex_app/automation_update with no call_id and no matching preceding function_call.
    • The provider returns: Invalid Value: 'input.call_id'. Function call output requires call_id.
    • Earlier scheduled runs on CLI 0.149.0-alpha.4.3 and 0.150.0-alpha.12.2 contain matching call_id values and complete successfully.
  7. guoqunabc commented on Sep 9, 2026

    @guoqunabc

    Additional reproduction on September 9, 2026: this still affects native scheduled automations on bundled CLI 0.153.4.

    Environment:

    • Codex Desktop 26.901.51231, build 8109, macOS Apple Silicon
    • Bundled CLI/app-server 0.153.4 (confirmed in the failed run metadata)
    • Provider: Azure; model: gpt-5.6-luna
    • Automation: native local cron

    The first turn failed after 4,543 ms, before any maintenance command or assistant response. The persisted bootstrap response item has this shape (production prompt omitted):

    {
      "type": "function_call_output",
      "name": "automation_update",
      "namespace": "codex_app",
      "output": "<automation context and prompt omitted>"
    }

    There is no call_id key, and no preceding matching function_call. The returned error is:

    Invalid Value: 'input.call_id'. Function call output requires call_id.
    

    Read-only inspection of this installed Desktop bundle also found the automation input helper selects toolOutput when the app-server version supports turnToolOutput; its existing fallback supplies ordinary text input. The capability threshold is 0.151.0-alpha.4. This appears to explain why current app-server versions take the problematic path. This is a local code observation, not a verified upstream fix.

    Please consider provider-aware normalization or using the existing text-input path for unsolicited automation bootstrap content, so it does not become an orphaned function output.

    No application patch, proxy, scheduler replacement, or history modification was applied. A native fix is needed. Local usernames, paths, task IDs, endpoint details, credentials, and the production automation prompt have been omitted.

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

    appIssues related to the Codex desktop appapp-serverIssues involving app server protocol or interfacesautomationsazureIssues related to the Azure-hosted OpenAI modelsbugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions