Skip to content

Console Go web_search_call 400: input[N].action missing required field query on replayed multi-query search #3071

Closed

Description

@justin-mc-lai

Client or integration

Codex CLI

Area

Provider adapter / Tools / MCP / web search

Summary

Using opencode-go/muse-spark-1.2-contributor on the native Responses route, a conversation that performed a multi-query web search 400s on every subsequent turn: input[N].action missing required field query (Console Go). Sibling of the queries missing-field bug (#930/#929): DeepSeek native Responses needs plural queries, Console Go's upstream validator needs singular query, and webSearchAction() only emitted queries for multi-query batches. The offending web_search_call item is replayed in the history of every request, so the thread is permanently poisoned until repaired.

Reproduction

  1. Run OpenCodex 2.37.0 with the opencode-go provider and opencode-go/muse-spark-1.2-contributor.
  2. In one Codex session, have the model perform a web search with more than one query so the bridge records {type:"web_search_call", action:{type:"search", queries:[...]}} (no singular query).
  3. Continue the conversation for another turn (the item is replayed at input[N]).
  4. Observe 400: Error from provider (Console Go): Upstream request failed: [invalid_request_error] input[N].actionmissing required fieldquery``.

Pre-fix repro via a direct replay: POST /v1/responses with {type:"web_search_call", action:{type:"search", queries:["a","b"]}} in input => 400 missing query; with singular query present => 200.

Version

2.37.0

Operating system

macOS (Darwin)

Provider and model

opencode-go / muse-spark-1.2-contributor

Logs or error output

{"model":"muse-spark-1.2-contributor","error":{"param":"input[240].action","type":"invalid_request_error","message":"Error from provider (Console Go): Upstream request failed: [invalid_request_error] `input[240].action` missing required field `query`"}}

Redacted configuration

{"providers":{"opencode-go":{"adapter":"openai-chat","baseUrl":"https://opencode.ai/zen/go/v1","defaultModel":"deepseek-v4-flash","models":["deepseek-v4-flash","muse-spark-1.2-contributor"]}}}

Checks

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

Fix proposal (PR #3069): webSearchAction() now always emits action.query (first query) alongside queries; backfillWebSearchQueries() heals previously recorded items in either missing direction.

Activity

  1. added
    bugSomething isn't working
    toolstool_calls, MCP, web-search / sidecar tools
    on Aug 31, 2026
  2. lidge-jun commented on Aug 31, 2026

    @lidge-jun
    Owner

    리뷰 · 우선순위 49 / 80

    이 이슈는 OpenCode Go(저장소 주석의 Console Go / Zen Go)에서 muse-spark-1.2-contributor를 네이티브 Responses로 쓸 때, 예전에 기록된 여러 검색어 web_search_call이 다음 턴마다 400을 내는 버그입니다. 지금 dev HEAD는 7ee96b94e(#3058, 패키지 2.38.0)입니다. opencode-go는 src/providers/registry.ts 1454행입니다. 기본 어댑터는 openai-chat이고, GPT 5.6 Luna와 Muse Spark만 modelWireDefaults로 openai-responses를 탑니다(1468행). Muse Spark 창은 1M입니다(#2785, 1477행). Muse만 web_search.search_content_types를 빼는 코드는 src/adapters/openai-responses.ts stripMuseSparkUnsupportedWebSearchFields(1878행, 호출 2139행)입니다. 이 400은 그 필드가 아닙니다. 히스토리에 남은 검색 아이템에 단수 query가 없어서입니다.

    같은 제목의 #3068이 이미 열려 있습니다. 작성자도 justin-mc-lai로 같습니다. #3068은 처음에 템플릿이 없어서 품질 봇이 닫았다가 다시 열렸고, 그 리뷰에서 버그 템플릿을 채우라고 했습니다. 이 이슈(#3071)가 그 템플릿을 채운 재작성입니다. 재현 단계, 직접 POST 재현, input[240].action 로그, 설정 JSON까지 있습니다. 고치는 PR은 본문이 가리킨 #3069뿐입니다. types.ts/config.ts 분할과 무관합니다. #2908(보내기 시각 providerFetch HTTP 버전), #2712(opt-in x_search), #2932(사이드카 루프 recovery)와는 층이 다릅니다.

    지금 HEAD의 src/bridge.ts webSearchAction(164행)은 검색어가 하나이거나 비면 { type:"search", query, queries:[query] }를 넣습니다. 검색어가 둘 이상이면 { type:"search", queries }만 넣고 단수 query는 빼 둡니다. 이 비대칭은 주석(149–159행)이 일부러 잠근 계약입니다. DeepSeek 네이티브 Responses 파서는 queries가 없으면 다음 턴마다 missing field 'queries'로 400을 냅니다(#930, 이미 닫힘). 그래서 단수 쪽에 queries를 넣었습니다. 반대로 codex-rs는 칸 제목을 단수 query에서 읽고, query가 없고 queries.len() > 1일 때만 " ..." 말줄임표를 그립니다. 배치에 query를 넣으면 그 말줄임표가 사라집니다.

    src/adapters/openai-responses.ts backfillWebSearchQueries(916행)는 예전에 단수만 기록된 아이템에 queries:[query]를 채워 줍니다. query가 문자열이고 queries가 배열이 아닐 때만 고칩니다(923행). 배치 아이템은 그대로 둡니다. 이 함수는 buildRequest 2103행에서 Responses 요청마다 돌아서, OpenCode Go로 나가는 히스토리에도 적용됩니다. Muse 전용 필드 제거(2139행)보다 앞입니다.

    그래서 배치 검색이 한 번 기록되면, 그 action에는 queries만 있습니다. Console Go 업스트림 검사기는 단수 query를 필수라고 보고 input[N].action missing required field query 400을 냅니다. 그 아이템은 같은 대화의 이후 요청마다 다시 실려 가서, 프록시를 올려도 그 대화는 영원히 막힙니다. 본문이 적은 재현(opencode-go/muse-spark-1.2-contributor, 버전 2.37.0, input[240].action)과 HEAD 코드가 맞습니다. 형제 이슈 #930과 같은 종류의 재현이고, 빠진 키만 반대입니다. 직접 재생 재현(배치 아이템 POST → 400, 단수 query 있으면 200)도 본문에 있습니다.

    고치는 방향도 본문이 맞게 적었습니다. 앞으로 만드는 아이템은 webSearchAction이 항상 query(첫 검색어)와 queries를 같이 넣고, 예전에 기록된 아이템은 백필이 빠진 쪽을 채웁니다. 그 코드는 이미 PR #3069에 있습니다. 다만 그 PR은 베이스가 main이라 제목에 [WRONG BRANCH]가 붙었고, 초안이며, 체크리스트가 비어 있고, HEAD가 잠가 둔 테스트 두 개를 안 바꿨습니다. tests/bridge.test.ts 1078행은 배치에 query가 없기를 기대합니다. tests/openai-responses-passthrough.test.ts 1324행은 백필이 배치를 그대로 두기를 기대합니다. 이 이슈만 닫아도, #3069를 지금 형태 그대로 머지해도, 사용자는 계속 400을 봅니다.

    경로 src/bridge.ts webSearchAction 164행 - 배치 검색은 query 없이 queries만 넣는다. Console Go가 다음 턴마다 400을 내는 바로 그 모양이다
    경로 src/adapters/openai-responses.ts backfillWebSearchQueries 923행 - query가 문자열이고 queries가 배열이 아닐 때만 고친다. 배치 히스토리는 고치지 않아서 업그레이드만으로는 대화가 안 풀린다
    경로 tests/bridge.test.ts 1078행 - 배치에 query가 없기를 잠근다. 고침이 이 단언을 같이 뒤집지 않으면 CI가 막는다
    경로 tests/openai-responses-passthrough.test.ts 1324행 - 백필이 배치를 그대로 두기를 잠근다. Console Go 방향의 반대 단언이 없다
    경로 이슈 #3068 - 같은 제목, 같은 작성자, 같은 버그. 템플릿 없는 원본이다. 이 이슈가 그 재작성이다
    경로 PR #3069 - 고치는 파일은 맞다. 다만 베이스가 main이고 테스트가 없고 초안·체크리스트 0/4라서, 이 이슈를 지금 닫을 근거가 못 된다

    메인테이너의 판단이 필요한 지점

    너의 추천
    이 이슈는 진짜다. HEAD의 배치 web_search_call 모양이 Console Go에서 대화를 막습니다. #3068과 내용은 같고, 이쪽이 버그 템플릿을 채운 정식 본문이니 #3071을 남기고 #3068은 중복으로 닫으세요. 고침은 #3069 한곳으로 모으세요. 그 PR을 dev로 돌리고, 배치 테스트 두 개를 새 계약으로 바꾸고, queries[0]이 문자열일 때만 query를 채우게 한 뒤에 머지하면 이 이슈를 닫으면 됩니다. 지금은 이 이슈를 닫지 마세요. types/config 분할 무효화 해당 없음. 프리뷰 배포는 계획에 없습니다.

    이 댓글은 grok-bot이 작성했습니다

  3. lidge-jun commented on Aug 31, 2026

    @lidge-jun
    Owner

    Fixed on dev in a0d386b49 (#3089), carrying @kunqi.lai's commits from #3069 with authorship preserved.

    webSearchAction() now emits both query and queries in every case. The batch omission was defended in a comment as necessary for codex-rs rendering — it renders " ..." only when query is absent and queries.len() > 1 — so the fix trades that ellipsis for a validator pass and says so in the comment, since the old one argued for the shape being removed.

    backfillWebSearchQueries() repairs stored history in both directions, with three guards added after two review rounds:

    • an empty queries: [] canonicalizes to the bridge's empty-search shape, keeping an existing query rather than discarding it;
    • the singular field is derived from a plural array only when every member is a string — deriving from ["a", 42] would satisfy Console Go and leave DeepSeek to reject the same replay;
    • a wholly malformed array is left untouched, because coercing or dropping members would invent semantics the stored item never had.

    #3068 is closed as a duplicate. Verified on repository CI at the exact merged head: 23 checks green across Linux, macOS and Windows.

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 workingtoolstool_calls, MCP, web-search / sidecar tools

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions