Skip to content

Rate‑limit 429 causes Codex CLI abort / raw‑mode crash #157

Closed

Description

@smartpuppy

Environment

  • CLI version: codex --version → v0.1.04161006
  • Model: o3
  • OS: macOS Sequoia 15.4 (Apple Silicon)
  • Node.js: v23.10.0
  • Org ID: org‑REDACTED

Steps to reproduce

  1. Run codex --model o3 edit (interactive mode)
  2. Submit a large apply_patch block (~29 k tokens)
  3. CLI retries once, then receives 429 → Ink raw‑mode crash

Observed error

[Error]: Rate limit reached for o3 in organization org‑REDACTED on tokens per min (TPM): Limit 30000, Used 23669, Requested 29142. Please try again in 45.622s. Visit https://platform.openai.com/account/rate-limits to learn more.
at e.a [as iterator] (file:///opt/homebrew/lib/node_modules/@openai/codex/dist/cli.js:443:1514)
at process.processTicksAndRejections (node:internal/process/task_queues:105:5)
at async I0.run (file:///opt/homebrew/lib/node_modules/@openai/codex/dist/cli.js:460:2356) {
status: undefined,
headers: undefined,
request_id: undefined,
error: {
type: 'tokens',
code: 'rate_limit_exceeded',
message: 'Rate limit reached for o3 in organization org-REDACTED on tokens per min (TPM): Limit 30000, Used 23669, Requested 29142. Please try again in 45.622s. Visit https://platform.openai.com/account/rate-limits to learn more.',
param: null
},
code: 'rate_limit_exceeded',
param: null,
type: 'tokens'
}

The session aborts; partial patch is lost.

Expected behavior

  • CLI should automatically back‑off or chunk large patches after a 429
  • No fatal crash when Ink UI fails to enter raw mode

Possible improvements

  • Document OPENAI_MAX_RETRIES / OPENAI_MS_BETWEEN_RETRIES
  • Auto‑chunk patches > 30 k tokens
  • Default to --no-ui on automatic retries to avoid raw‑mode issues

Activity

  1. tibo-openai commented on Apr 17, 2025

    @tibo-openai
    Collaborator

    Submitted #153, could you build from source and verify that this fixed your issue?

  2. edwardsmoses commented on Apr 17, 2025

    @edwardsmoses

    Adding this in case it might be helpful in any way, on version 0.1.2504161551:

    Image

  3. smartpuppy commented on Apr 17, 2025

    @smartpuppy
    Author

    Follow‑up: CLI still exits after second 429

    PR #153 fixed the Ink raw‑mode crash (thanks!), but the CLI still aborts
    entirely once it receives a second 429 in the same request cycle. This forces
    the user back to the shell and loses context.

    Steps to reproduce

    1. codex --model o3 edit (interactive or --no-ui)
    2. Submit a patch > 25 k tokens so total usage > 30 k TPM.
    3. CLI prints first 429 → retries → immediately receives second 429 →
      process exits (status 1).

    Expected

    • CLI should respect OPENAI_MAX_RETRIES / OPENAI_MS_BETWEEN_RETRIES
      by default, or prompt the user rather than exiting.
    • Alternatively, auto‑chunk large patches so a single request never exceeds the
      TPM bucket.

    Environment is the same as in #157 (macOS 15.4, Node 23.10.0, CLI 0.1.2504161510).

  4. smartpuppy commented on Apr 17, 2025

    @smartpuppy
    Author

    FYI:

    Additional stack (first frames):

    file:///Users/west/Code/codex‑cli-fix/codex‑cli/dist/cli.js:445:…
    at e.a [as iterator] (.../cli.js:443:1514)
    at async I0.run (.../cli.js:460:2356)

    (full minified trace available if needed)

  5. smartpuppy commented on Apr 17, 2025

    @smartpuppy
    Author

    A NOTE FOR CLARIFICATION

    I apologize for this part of the response "PR #153 fixed the Ink raw‑mode crash (thanks!)" that has nothing to do with the issue. o3 was helping me troubleshoot and hallucinated that that was part of the bug.

    I only caught what was going on after re-checking the logs.

    From o3 attempting to set the record straight :

    Clarification (16 Apr 2025)

    My earlier description reused the phrase “Ink raw‑mode crash,” but that
    specific error line is not present in my current logs.

    What I’m seeing now is:

    1. I send a large apply_patch (> 30 k tokens total).
    2. CLI gets a rate_limit_reached (429), waits, retries once.
    3. Second 429 arrives → CLI exits cleanly (status 1) and drops back to the
      shell, so the patch is lost.

    No Raw mode is not supported... line appears, and the terminal is not in a
    broken state; the program just quits after the second 429.

    Request: have the CLI keep backing‑off (or auto‑chunk the patch) instead of
    quitting after one retry.

  6. NPM8 commented on Apr 17, 2025

    @NPM8

    Same here on o4-mini. In most cases I can't go to any meaningful with any request most of them take more then rate limit is so it's hard to do anything.

  7. psalkowski commented on Apr 17, 2025

    @psalkowski

    Same here, we had announcement of gpt-4.1 and Codex CLI, but seems it's not usable for personal use as it exceed token limits. I asked for fix unit tests where I do a special error to see how it handles it, and well.. Request too large for gpt-4.1 in organization org-gZ... on tokens per min (TPM): Limit 30000, Requested 81483

  8. felixbuenemann commented on Apr 17, 2025

    @felixbuenemann

    Also seeing this with o4-mini and codex v0.1.2504161551. Codex should just wait the time given by the server and retry:

    file:///opt/homebrew/lib/node_modules/@openai/codex/dist/cli.js:445
    …
    e [Error]: Rate limit reached for o4-mini in organization org-{redacted} on tokens per min (TPM): Limit 200000, Used 152566, Requested 60651. Please try again in 3.965s. Visit https://platform.openai.com/account/rate-limits to learn more.
        at e.a [as iterator] (file:///opt/homebrew/lib/node_modules/@openai/codex/dist/cli.js:445:1514)
        at process.processTicksAndRejections (node:internal/process/task_queues:105:5)
        at async R0.run (file:///opt/homebrew/lib/node_modules/@openai/codex/dist/cli.js:462:2639) {
      status: undefined,
      headers: undefined,
      request_id: undefined,
      error: {
        type: 'tokens',
        code: 'rate_limit_exceeded',
        message: 'Rate limit reached for o4-mini in organization org-{redacted} on tokens per min (TPM): Limit 200000, Used 152566, Requested 60651. Please try again in 3.965s. Visit https://platform.openai.com/account/rate-limits to learn more.',
        param: null
      },
      code: 'rate_limit_exceeded',
      param: null,
      type: 'tokens'
    }
    
    Node.js v23.10.0
    
  9. tibo-openai commented on Apr 17, 2025

    @tibo-openai
    Collaborator

    WIP pull request in:
    #176

  10. tibo-openai commented on Apr 17, 2025

    @tibo-openai
    Collaborator

    Related fix in #266, should work if you build and run from main.

  11. rjlee commented on Apr 18, 2025

    @rjlee
    npm list -g
    /Users/me/.nvm/versions/node/v22.14.0/lib
    ├── @openai/codex@0.1.2504172351
    
    codex "Explain the functionality in this respository"
    ...
    
    e [Error]: Rate limit reached for o4-mini in organization org-XXX on tokens per min (TPM): Limit 200000, Used 166336, Requested 65332. Please try again in 9.5s. Visit https://platform.openai.com/account/rate-limits to learn more.
        at e.a [as iterator] (file:///Users/me/.nvm/versions/node/v22.14.0/lib/node_modules/@openai/codex/dist/cli.js:449:1514)
        at process.processTicksAndRejections (node:internal/process/task_queues:105:5)
        at async T0.run (file:///Users/me/.nvm/versions/node/v22.14.0/lib/node_modules/@openai/codex/dist/cli.js:466:2933) {
      status: undefined,
      headers: undefined,
      request_id: undefined,
      error: {
        type: 'tokens',
        code: 'rate_limit_exceeded',
        message: 'Rate limit reached for o4-mini in organization org-XXX on tokens per min (TPM): Limit 200000, Used 166336, Requested 65332. Please try again in 9.5s. Visit https://platform.openai.com/account/rate-limits to learn more.',
        param: null
      },
      code: 'rate_limit_exceeded',
      param: null,
      type: 'tokens'
    }
    

    Latest release still experiences the issue.

  12. hybridpicker commented on Apr 18, 2025

    @hybridpicker

    Just wanted to confirm I'm also affected by this rate limit handling issue with gpt-4.1. The CLI stopping instead of waiting is the main pain point.

    Echoing the previous comments, the ideal solution would be for the CLI to automatically parse the "Please try again in X.Xs" time from the 429 error message, wait that duration, and then retry the request. Having this built-in would make codex cli much more robust. Hope this fix can be prioritized.

  13. stacode123 commented on Apr 18, 2025

    @stacode123

    Built from main.Problem still exists
    e [Error]: Rate limit reached for o4-mini in organization org-s1NXN1xEWxsFLjqXYxQoz1Mi on tokens per min (TPM): Limit 200000, Used 141821, Requested 58778. Please try again in 179ms

  14. pascudder commented on Apr 18, 2025

    @pascudder

    I've created a PR with a fix that's been working for me

    #357

  15. williamspencer commented on Apr 19, 2025

    @williamspencer

    still experiencing this on latest build

  16. smartpuppy commented on Apr 20, 2025

    @smartpuppy
    Author

    Heap‑out‑of‑memory while loading large patch (blocks 429‑retry testing)

    • codex‑cli 0.1.250419 (npm)
    • Node v23.10.0_1 (Apple M4 Max, macOS 15.4)
    • Patch size 849 KB
    # command used
    DEBUG=codex* codex apply_patch -f huge.diff --model o4-mini --no-ui
    
    # result
    FATAL ERROR: Reached heap limit – Allocation failed (JavaScript heap out of memory)
    Even with NODE_OPTIONS=--max-old-space-size=8192 the CLI crashes before any network request, so I can’t verify whether the 429‑retry fix in PR #266 / #176 works.
    
    [codex_repro.log.gz](https://github.com/user-attachments/files/19823451/codex_repro.log.gz)
    
  17. smartpuppy commented on Apr 20, 2025

    @smartpuppy
    Author

    Oh and btw - rate limit bug is still happening too:

    codex‑cli 0.1.250419 (npm)
    Node v23.10.0_1 (Apple M4 Max, macOS 15.4)

    file:///opt/homebrew/lib/node_modules/@openai/codex/dist/cli.js:449
    ,"\r"]);gg.NEWLINE_REGEXP=/\r\n|[\n\r]/g;function uwe(e,t){for(let a=t??0;a<e.length;a++){if(e[a]===10)return{preceding:a,index:a+1,carriage:!1};if(e[a]===13)return{preceding:a,index:a+1,carriage:!0}}return null}function pae(e){for(let n=0;n<e.length-1;n++){if(e[n]===10&&e[n+1]===10||e[n]===13&&e[n+1]===13)return n+2;if(e[n]===13&&e[n+1]===10&&n+3<e.length&&e[n+2]===13&&e[n+3]===10)return n+4}return-1}g();function IO(e){if(e[Symbol.asyncIterator])return e;let t=e.getReader();return{async next(){try{let r=await t.read();return r?.done&&t.releaseLock(),r}catch(r){throw t.releaseLock(),r}},async return(){let r=t.cancel();return t.releaseLock(),await r,{done:!0,value:void 0}},[Symbol.asyncIterator](){return this}}}var id=class e{constructor(t,r){this.iterator=t,this.controller=r}static fromSSEResponse(t,r){let n=!1;async function*a(){if(n)throw new Error("Cannot iterate over a consumed stream, use .tee()to split the stream.");n=!0;let i=!1;try{for await(let s of dwe(t,r))if(!i){if(s.data.startsWith("[DONE]")){i=!0;continue}if(s.event===null||s.event.startsWith("response.")||s.event.startsWith("transcript.")){let c;try{c=JSON.parse(s.data)}catch(d){throw console.error("Could not parse message into JSON:",s.data),console.error("From chunk:",s.raw),d}if(c&&c.error)throw new mi(void 0,c.error,void 0,wO(t.headers));yield c}else{let c;try{c=JSON.parse(s.data)}catch(d){throw console.error("Could not parse message into JSON:",s.data),console.error("From chunk:",s.raw),d}if(s.event=="error")throw new mi(void 0,c.error,c.message,void 0);yield{event:s.event,data:c}}}i=!0}catch(s){if(s instanceof Error&&s.name==="AbortError")return;throw s}finally{i||r.abort()}}return new e(a,r)}static fromReadableStream(t,r){let n=!1;async function*a(){let s=new gg,c=IO(t);for await(let d of c)for(let f of s.decode(d))yield f;for(let d of s.flush())yield d}async function*i(){if(n)throw new Error("Cannot iterate over a consumed stream, use.tee() to split the stream.");n=!0;let s=!1;try{for await(let c of a())s||c&&(yield JSON.parse(c));s=!0}catch(c){if(c instanceof Error&&c.name==="AbortError")return;throw c}finally{s||r.abort()}}return new e(i,r)}[Symbol.asyncIterator](){return this.iterator()}tee(){let t=[],r=[],n=this.iterator(),a=i=>({next:()=>{if(i.length===0){let s=n.next();t.push(s),r.push(s)}return i.shift()}});return[new e(()=>a(t),this.controller),new e(()=>a(r),this.controller)]}toReadableStream(){let t=this,r,n=new TextEncoder;return new mN({async start(){r=t[Symbol.asyncIterator]()},async pull(a){try{let{value:i,done:s}=await r.next();if(s)return a.close();let c=n.encode(JSON.stringify(i)+

    e [Error]: Rate limit reached for o3 in organization org-xxx on tokens per min (TPM): Limit 450000, Used 389392, Requested 70032. Please try again in 1.256s. Visit https://platform.openai.com/account/rate-limits to learn more.
    at e.a [as iterator] (file:///opt/homebrew/lib/node_modules/@openai/codex/dist/cli.js:449:1514)
    at process.processTicksAndRejections (node:internal/process/task_queues:105:5)
    at async T0.run (file:///opt/homebrew/lib/node_modules/@openai/codex/dist/cli.js:466:2933) {
    status: undefined,
    headers: undefined,
    request_id: undefined,
    error: {
    type: 'tokens',
    code: 'rate_limit_exceeded',
    message: 'Rate limit reached for o3 in organization org-xxx on tokens per min (TPM): Limit 450000, Used 389392, Requested 70032. Please try again in 1.256s. Visit https://platform.openai.com/account/rate-limits to learn more.',
    param: null
    },
    code: 'rate_limit_exceeded',
    param: null,
    type: 'tokens'
    }

    Node.js v23.10.0

  18. tibo-openai commented on Apr 29, 2025

    @tibo-openai
    Collaborator

    This was now fixed a while ago, and going to close this. Please ensure that you are running the latest version here: https://github.com/openai/codex/blob/main/CHANGELOG.md#012504251709

    You should see

    $ codex --version
    0.1.2504251709
    
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

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions