Skip to content

[Bug] Codex Desktop wait.yield_time_ms / max_tokens still rejected as 120000.0 after #2316 #2443

Closed

Description

@lidge-jun

Client or integration

Codex App

Area

Tools / MCP / web search

Summary

On current origin/dev (bf8bcfd3c8, npm @bitkyc08/[email protected]), Grok-routed Codex Desktop still rejects the host wait tool before it runs:

failed to parse function arguments: invalid type: floating point `120000.0`, expected u64 at line 1 column 40
failed to parse function arguments: invalid type: floating point `8000.0`, expected usize at line 1 column 35

The model intended integers. Codex advertises both fields as JSON Schema number, then deserializes them as Rust u64 / usize. OpenCodex already repairs this class of argument in src/lib/tool-argument-integers.ts (#1611, #2316), but the #2316 allowlist is still only timeout_ms. The file even says Cursor/Codex yield_time_ms is declared number and is not included until a live rejection exists. This session is that rejection.

Expected: an integral float in a Codex-native integer field is rewritten to an integer, wait continues the exec cell, and Aside/long-running host work can be polled. A genuine fraction such as 1.5 must still fail.

This is not an Aside bug. Aside CLI updated and executed; the host wait poll never attached because Codex rejected the function-call arguments.

Reproduction

  1. Route Codex App / Codex Desktop through OpenCodex with default provider xAI Grok (xai/grok-4.6 in this session).

  2. Start a long-running host command through code-mode exec / exec_command so it yields with a cell id, e.g. aside exec "...".

  3. Call the Codex Desktop host tool wait with integer arguments:

    {"cell_id":"29","yield_time_ms":120000}
    {"cell_id":"30","max_tokens":8000}

    Grok serializes those fields as 120000.0 / 8000.0.

  4. Observe the parse rejections above. wait does not run. The underlying process (Aside, in this case) keeps running independently.

Live schema advertised to the model in this session (both integer-runtime fields are JSON Schema number):

{
  "name": "wait",
  "parameters": {
    "type": "object",
    "required": ["cell_id"],
    "properties": {
      "cell_id": { "type": "string" },
      "yield_time_ms": { "type": "number" },
      "max_tokens": { "type": "number" },
      "terminate": { "type": "boolean" }
    }
  }
}

Current allowlist in src/lib/tool-argument-integers.ts:

const U64_NUMBER_FIELDS = new Set(["timeout_ms"]);

Comment immediately above that set says yield_time_ms is excluded until a reproduction is captured. Add yield_time_ms and max_tokens only if they remain Codex-native integer fields (u64 / usize) with this same hard reject.

Related: #1611, #2316. #2316 fixed multi_agent_v1__wait_agent.timeout_ms; this is a different host tool (wait) with the same serializer/runtime mismatch.

Version

npm @bitkyc08/[email protected] / origin/dev bf8bcfd3c8a2cb1a352d4419351f634c3d3e75b4

Local checkout package.json still prints 2.27.0; that file is stale relative to the published tag. The live reject is from Codex Desktop routed through OpenCodex, not from Aside.

Operating system

macOS 27.0 (26A5378n)

Provider and model

xai / grok-4.6 (OpenCodex default provider; Codex App / Codex Desktop host tool surface)

Logs or error output

failed to parse function arguments: invalid type: floating point `120000.0`, expected u64 at line 1 column 40
failed to parse function arguments: invalid type: floating point `8000.0`, expected usize at line 1 column 35

Independent evidence that Aside itself was healthy while wait was rejected:

  • aside --update installed 1.26.810.1915
  • aside exec opened https://arca.live/b/stock/180813968?p=1 and read the page
  • process aside exec ... remained running after the wait parse failures
  • session dir ~/.aside/u/0/sessions/2026-08-23_7We16YtbYllIs0tv kept growing messages.jsonl

Checks

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

Activity

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

    @lidge-jun
    OwnerAuthor

    리뷰 · 우선순위 60 / 80

    설명: 이 이슈는 2316 이 timeout_ms 만 고친 뒤에, 코덱스 데스크톱 호스트 도구 wait 의 yield_time_ms 와 max_tokens 가 아직도 소수로 거절된다고 한다. 지금 CURRENT dev HEAD 는 bf8bcfd3c 이다. 이번 시간에 origin/dev 는 그 자리에서 안 움직였다. 새 머지는 없다. package.json 은 2.27.0 이다. src/config.ts 는 3975줄이다. src/runtime 폴더는 지금 HEAD 에 없다. 작성자는 오너이고, 지금 HEAD bf8bcfd3c 와 배포 2.31.0 에서 재현했다. 내가 HEAD 를 열어 보니 허용 목록은 아직 timeout_ms 하나다.

    재현은 이렇다. 코덱스 앱을 기본 제공자 엑스에이아이 그록으로 보낸다. 긴 호스트 명령을 실행해서 칸 아이디가 나온다. 모델은 wait 에 정수 뜻을 담는다. 그록이 그 칸을 120000.0 과 8000.0 으로 직렬화한다. 코덱스는 그 값을 유64 와 유사이즈로 읽다가 거절한다. wait 는 실행되지 않는다. 아래 프로세스 자체는 살아 있다. 이건 어사이드 버그가 아니다. 호스트 wait 폴이 인자 파싱에서 막힌 것이다. 기대는 정수 뜻의 소수를 정수로 고쳐서 wait 가 이어지고, 진짜 소수 1.5 는 그대로 실패하는 것이다.

    지금 HEAD 의 src/lib/tool-argument-integers.ts 62줄 주석은 2316 의 wait_agent timeout_ms 를 말한다. 75줄은 커서 형제 yield_time_ms 를 거절 증거가 없어서 안 넣었다고 적는다. 78줄 U64_NUMBER_FIELDS 는 timeout_ms 만 든다. 157줄은 그 목록 이름이고 숫자 스키마일 때만 고친다. tests/tool-argument-integers.test.ts 328줄 시험은 yield_time_ms 가 스키마 number 이면 120000.0 을 그대로 둔다고 잠근다. 같은 파일 35줄 실행 스키마는 yield_time_ms 를 integer 로 적어서 그 길로 고친다. 작성자가 본 코덱스 wait 스키마는 두 칸 모두 number 다. 그래서 스키마 integer 길은 이 거절을 못 고친다. 허용 목록만 고친다.

    max_tokens 는 이름이 너무 넓다. 75줄 주석이 start, end, priority, port 같은 일반 이름을 경고한 바로 그 이유다. wait 도구에만 묶지 않고 전역 목록에 넣으면, 소수를 진짜로 받는 다른 도구의 max_tokens 를 정수로 바꿔 버릴 수 있다. yield_time_ms 는 주석이 증거를 기다리던 그 이름이고, 이번 세션이 그 거절이다. 다만 이 이슈의 wait 는 코덱스 네이티브 호스트 도구다. 커서 형제와 같은 이름이어도, 커서 쪽을 이 이슈만으로 같이 고치지 않는 편이 맞다. 1611 과 2316 은 다른 도구다. 2316 은 wait_agent 의 timeout_ms 다. 이 이슈는 wait 다. 둘을 한 이슈로 묶지 않는다.

    고치는 풀 리퀘스트는 아직 없다. 착지 전에는 이 이슈를 닫지 않는다. 사용자 길이로는 긴 호스트 일을 기다리다가 wait 가 인자 파싱에서 죽는 구멍이라서 60. 카탈로그 팁은 Ox Alpha x-preview-f-free + deepseek-v4-flash-vision-exp. Cursor 정적 카탈로그는 opus-4-8-fast / opus-5-fast. 2334 CursorCredentialRouter 는 여전히 src/providers/cursor-pool.ts 모듈+테스트만 있고 어댑터에 연결되지 않았다. 2332 H2 는 discovery 전용. 2320 overflow + 2342 는 이미 dev. 2188 사이드카는 이미 dev. 2382 데스크톱 앱 재시작은 이미 dev. 2361 __omit__ 는 이미 HEAD 다. 2292 는 아직 연다. 지금 HEAD 의 남은 구멍은 그대로다. src/lib/bounded-body.ts 128줄은 이미 죽은 시그널에서 취소 없이 던진다. 222줄 본문 읽기는 취소한다. 2426 코덱스 웹소켓 나가는 크기 가드는 없다. 2431 빈 에스에스와 410 구멍은 그대로다. combo-stream-preflight.ts 는 HEAD 에 없다. 2434 가져오기 복사 import 도 그대로다. history-manifest.ts 는 HEAD 에 없다.

    src/lib/tool-argument-integers.ts 라인 75 - 주석이 yield_time_ms 를 거절 증거가 없어서 빼 두었다. 이번이 그 거절이다
    src/lib/tool-argument-integers.ts 라인 78 - 허용 목록은 timeout_ms 하나다. wait 의 두 칸은 없다
    src/lib/tool-argument-integers.ts 라인 157 - 목록 이름이고 숫자 스키마일 때만 고친다. 진짜 소수 1.5 는 그대로 둔다
    tests/tool-argument-integers.test.ts 라인 328 - 스키마 number 인 yield_time_ms 는 지금 고치지 않는다고 잠근다
    src/bridge.ts 라인 627 - 이 고침이 도구 인자 문자열에 붙는 다리다
    이슈 2316 - wait_agent 의 timeout_ms 다. 이 이슈의 wait 와 다른 도구다. 이 이슈만으로 닫지 않는다

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

    • yield_time_ms 를 허용 목록에 넣을지. 주석이 기다리던 거절이 이번에 왔다. 넣는 편이 맞다
    • max_tokens 를 전역 목록에 넣을지. 이름이 넓어서 wait 도구에만 묶는 편이 맞다
    • 커서 형제의 yield_time_ms 를 같이 넣을지. 이번 거절은 코덱스 네이티브 wait 다. 커서 쪽은 따로 증거가 오면 한다
    • 2316 과 한 이슈로 묶지 말 것. 도구 이름이 다르다
    • 2426 과 2431 과 2434 를 이 허용 목록 고침에 섞지 말 것

    너의 추천
    이슈는 열어 둔다. 고치는 PR 이 오면 그 PR 로 닫는다. yield_time_ms 는 허용 목록에 넣는다. max_tokens 는 wait 도구에만 묶거나, 코덱스 네이티브 정수 칸임이 유지될 때만 넣는다. 1.5 는 그대로 실패하게 둔다. 1611 과 2316 은 닫지 않는다. 호출 길을 넓히지 말 것. 라벨은 그대로 둔다. 프리뷰 배포가 아니다.

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

  3. lidge-jun commented on Aug 23, 2026

    @lidge-jun
    OwnerAuthor

    Fixed by #2448, squash-merged to dev as 81bf4b9.

    The bare wait tool's yield-time_ms and max_tokens are now coerced to integers on both bridge paths. #2316 only ever covered timeout_ms — src/lib/tool-argument-integers.ts:77 allowlisted that one name — so these two kept round-tripping as 120000.0 and 8000.0.

    The repair is scoped to the bare wait tool rather than added to the global allowlist, because both field names are ordinary: Cursor has its own yield_time_ms at src/adapters/cursor/tool-definitions.ts:42, and any third-party tool may legitimately want a fractional max_tokens. Negative cases are pinned too — 1.5 is preserved, and the same field names on other or namespaced tools stay byte-identical.

    Red-green verified: 33 pass / 2 fail before the source change, 35 pass / 0 fail after. CI green on the exact head.

  4. lidge-jun commented on Aug 23, 2026

    @lidge-jun
    OwnerAuthor

    Landed via #2448 at 81bf4b9

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 workinglanded-via-maintainerOriginal PR closed after landing via a maintainer merge traintoolstool_calls, MCP, web-search / sidecar tools

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions