Skip to content

[Bug]: sensenova hallucinates undeclared exec tool in subagent requests causing 502 stream disconnected #1795

Description

@yxr1995-maker

Client or integration

Codex App

Area

Provider adapter / bridge

Summary

When OpenCodex routes subagent requests (explorer, shadow calls via gpt-5.6-luna) to sensenova/sensenova-6.8-flash-lite, the model hallucinates tool calls to exec even when exec is not declared in the request tools. This triggers bridge.ts:998 validation failure, causing 502 and stream disconnect.

Error: routed provider emitted undeclared client tool "exec"; only request-declared tools may be called

Reproduction

  1. Configure shadowCallIntercept to route gpt-5.6-luna to sensenova/sensenova-6.8-flash-lite
  2. Codex spawns subagent (explorer) with limited tool set (search_files, read_file, etc., NO exec)
  3. sensenova sees system prompt mentioning exec capability and hallucinates tool call to exec
  4. bridge.ts:998 checks declaredToolNames.has("exec") -> false -> 502

Expected behavior

Undeclared tool calls from third-party providers should be tolerated (dropped with warning) instead of failing the entire turn. This is especially important for subagent/shadow calls where the model may see system prompts describing capabilities not available in the current request tool set.

Actual behavior

502 error: stream disconnected before completion

Version

OpenCodex 2.21.0

Operating system

macOS 27.0, Apple Silicon

Provider and model

Provider: sensenova
Model: sensenova-6.8-flash-lite
Adapter: openai-chat

Logs or error output

From usage.jsonl - 31 occurrences between 01:40-02:42 on 2026-08-16, all with gpt-5.6-luna -> sensenova routing:

provider: sensenova
model: sensenova-6.8-flash-lite
status: 502
upstreamError: routed provider emitted undeclared client tool "exec"; only request-declared tools may be called
requestedModel: gpt-5.6-luna
resolvedModel: sensenova-6.8-flash-lite

Proposed fix

In bridge.ts around line 998, when declaredToolNames check fails, drop the tool call and continue streaming instead of returning 502:

if (options?.declaredToolNames && !options.declaredToolNames.has(event.name)) {
console.warn("[opencodex] dropping undeclared tool call from routed provider");
break; // skip this tool call, continue stream
}

This allows the turn to complete with text response instead of failing entirely.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingtoolstool_calls, MCP, web-search / sidecar tools

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions