Skip to content

[bug] routed provider prefixes bare Codex tool with default.: default.view_image rejected as undeclared #4176

Description

@BangShou1st

Client or integration

Codex App

Area

Proxy / routing / tool-name normalization

Summary

A routed non-OpenAI model can emit the Codex view_image tool as default.view_image, which OpenCodex rejects as undeclared and aborts the stream:

stream disconnected before completion: routed provider emitted undeclared client tool "default.view_image"; only request-declared tools may be called

This still reproduces on OpenCodex 2.48.0.

The observed failure is similar to #3402 / #3403, but appears to be a different alias case.

#3403 fixed a declared namespaced tool whose provider echo used a different spelling:

default__apply_patch <-> default.apply_patch

This report is about a bare Codex tool being returned with an invented/default namespace:

view_image -> default.view_image

If the request declares bare view_image but does not declare default.view_image / default__view_image, the existing dotted ns.name alias support does not necessarily identify these as the same tool.

Current behaviour

  1. Codex exposes/uses the local view_image tool.
  2. A routed custom/non-OpenAI model or upstream compatibility layer returns the function call name as default.view_image.
  3. responses-undeclared-tool-guard treats it as a different, undeclared client tool.
  4. The SSE stream is aborted.
  5. Codex App shows reconnect attempts (reconnecting /5) and the turn fails.

Expected behaviour

OpenCodex should safely normalize a provider-added default. namespace back to the unique bare request-declared tool when that mapping is unambiguous.

For example, if the request-declared tool catalog contains exactly one bare tool named:

view_image

and does not contain a real namespaced tool whose canonical/alias name is default.view_image, then a provider echo of:

default.view_image

could be restored to:

view_image

before the undeclared-tool guard rejects it.

This should remain fail-closed when the mapping is ambiguous or the bare tool is not actually declared.

Suggested safety constraints

A conservative normalization could apply only when all of the following are true:

  1. The returned name has the form default.<name>.
  2. <name> is present as a request-declared bare tool.
  3. default.<name> / the corresponding namespaced identity is not itself a declared tool.
  4. The mapping resolves to exactly one declared tool identity.

Otherwise preserve the current undeclared-tool rejection.

This would avoid broadly stripping arbitrary namespaces while handling providers that serialize un-namespaced function calls under a synthetic default namespace.

Reproduction

  1. Run OpenCodex 2.48.0 with Codex App routed through a custom/non-OpenAI provider.
  2. Use a task that causes the model to inspect an image through Codex view_image.
  3. The routed provider returns default.view_image.
  4. Observe:
stream disconnected before completion: routed provider emitted undeclared client tool "default.view_image"; only request-declared tools may be called

Codex App then attempts to reconnect repeatedly.

Version

OpenCodex 2.48.0

Operating system

Windows

Provider and model

Custom / non-OpenAI routed model. The issue appears to be at the tool-call naming/compatibility boundary rather than in Codex's native OpenAI model path.

Related issues

Additional context

Prompt-level guidance in AGENTS.md was added to tell non-OpenAI models to use only request-declared tools and exact tool names, including explicitly avoiding invented prefixes such as default.. The failure still occurs, suggesting the default. prefix may be introduced by the model/provider tool-call serialization path rather than being reliably preventable through prompt instructions alone.

Checks

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 workingstreamingSSE, WebSocket, terminal stream frames

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions