You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Codex CLI exits abruptly on rate_limit_exceeded; should back-off & retry instead of closing #690
Run a long Codex CLI command that streams a large prompt + completion (≈70 k tokens).
codex 'explain this huge code base' --files src/**/*.py
Wait until total tokens in the last minute exceed 200 000 TPM.
What is the expected behavior?
CLI should:
Detect the rate_limit_exceeded error.
Wait for the retry-after window (OpenAI returns 2.515 s in this case) with exponential back-off.
Resume the same request or transparently re-send it, keeping the stream open.
Exit with a non-zero code only after exhausting configured retries.
What do you see instead?
The CLI throws an uncaught exception and terminates:
e [Error]: Rate limit reached for o4-mini … Limit 200000, Used 136502, Requested 71884 …
at file:///opt/homebrew/lib/node_modules/@openai/codex/dist/cli.js:445:1514
Node.js v23.11.0
All partial output is lost; the user must re-run the command manually.
Additional information
Running latest CLI via npm i -g @openai/codex.
No custom flags (--max-retries defaults to 0).
It would be safer to set a default retry policy (e.g., 3 attempts, exponential 2 → 4 → 8 s).
See full stack trace in the console log attached above.
I am still getting this issue in version 0.1.2504221401 which supposedly includes the commit (#506) that was to fix these issues.
For example:
w0 [Error]: 400 No tool output found for function call call_wyfQutQpE6tjvubx5WT84deI.
at e.generate (file:///Users/xxxxx/.n/lib/node_modules/@openai/codex/dist/cli.js:473:4010)
at Rr.makeStatusError (file:///Users/xxxxx/.n/lib/node_modules/@openai/codex/dist/cli.js:477:7623)
at Rr.makeRequest (file:///Users/xxxx/.n/lib/node_modules/@openai/codex/dist/cli.js:477:8555)
at process.processTicksAndRejections (node:internal/process/task_queues:105:5)
at async fE.run (file:///Users/xxxxxx/.n/lib/node_modules/@openai/codex/dist/cli.js:493:198) {
status: 400,
headers: {
'alt-svc': 'h3=":443"; ma=86400',
'cf-cache-status': 'DYNAMIC',
'cf-ray': '936a92bb4b5ba96d-SYD',
connection: 'keep-alive',
'content-length': '184',
'content-type': 'application/json',
date: 'Sun, 27 Apr 2025 01:33:41 GMT',
'openai-organization': 'personal-ayybqx',
'openai-processing-ms': '264',
'openai-version': '2020-10-01',
server: 'cloudflare',
'set-cookie': XXXXX,
'strict-transport-security': 'max-age=31536000; includeSubDomains; preload',
'x-content-type-options': 'nosniff',
'x-request-id': 'req_652445c72dbde625d65bb1cdc06945c0'
},
request_id: 'req_652445c72dbde625d65bb1cdc06945c0',
error: {
message: 'No tool output found for function call call_wyfQutQpE6tjvubx5WT84deI.',
type: 'invalid_request_error',
param: 'input',
code: null
},
code: null,
param: 'input',
type: 'invalid_request_error'
}
When I look into the logs I see it was because I exceeded quota with the offending request.
This is really bad UX as it blows away context and costs the user money without giving value.
I am kinda shocked by the state of this tool. It feels very broken.
This relates to pretty much any "failed" api request, they all crash out.
Error 400 / 500 / etc should all be handled similarly to rate limiting, retry with backoff.
IMO The only one that should likely be fail fast is an invalid key (as opposed to a rate limited key)
Many other API error responses are fleeting, either their server needs you to retry because they're flooded, or the LLM needs to retry with slightly different request/response to come up with a working message.
file:///Users/***/.nvm/versions/node/v22.14.0/lib/node_modules/@openai/codex/dist/cli.js:540
`,"\r"]);n_.NEWLINE_REGEXP=/\r\n|[\n\r]/g;function qFe(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 dle(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}m();function oB(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 Qd=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 o of VFe(t,r))if(!i){if(o.data.startsWith("[DONE]")){i=!0;continue}if(o.event===null||o.event.startsWith("response.")||o.event.startsWith("transcript.")){let c;try{c=JSON.parse(o.data)}catch(u){throw console.error("Could not parse message into JSON:",o.data),console.error("From chunk:",o.raw),u}if(c&&c.error)throw new bi(void 0,c.error,void 0,lB(t.headers));yield c}else{let c;try{c=JSON.parse(o.data)}catch(u){throw console.error("Could not parse message into JSON:",o.data),console.error("From chunk:",o.raw),u}if(o.event=="error")throw new bi(void 0,c.error,c.message,void 0);yield{event:o.event,data:c}}}i=!0}catch(o){if(o instanceof Error&&o.name==="AbortError")return;throw o}finally{i||r.abort()}}return new e(a,r)}static fromReadableStream(t,r){let n=!1;async function*a(){let o=new n_,c=oB(t);for await(let u of c)for(let f of o.decode(u))yield f;for(let u of o.flush())yield u}async function*i(){if(n)throw new Error("Cannot iterate over a consumed stream, use `.tee()` to split the stream.");n=!0;let o=!1;try{for await(let c of a())o||c&&(yield JSON.parse(c));o=!0}catch(c){if(c instanceof Error&&c.name==="AbortError")return;throw c}finally{o||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 o=n.next();t.push(o),r.push(o)}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 $O({async start(){r=t[Symbol.asyncIterator]()},async pull(a){try{let{value:i,done:o}=await r.next();if(o)return a.close();let c=n.encode(JSON.stringify(i)+`
e [Error]: Request too large for o3 in organization *** on tokens per min (TPM): Limit 30000, Requested 31608. The input or output tokens must be reduced in order to run successfully. Visit https://platform.openai.com/account/rate-limits to learn more.
at e.a [as iterator] (file:///Users/***/.nvm/versions/node/v22.14.0/lib/node_modules/@openai/codex/dist/cli.js:540:1514)
at process.processTicksAndRejections (node:internal/process/task_queues:105:5)
at async xE.run (file:///Users/***/.nvm/versions/node/v22.14.0/lib/node_modules/@openai/codex/dist/cli.js:557:2801) {
status: undefined,
headers: undefined,
request_id: undefined,
error: {
type: 'tokens',
code: 'rate_limit_exceeded',
message: 'Request too large for o3 in organization *** on tokens per min (TPM): Limit 30000, Requested 31608. The input or output tokens must be reduced in order to run successfully. Visit https://platform.openai.com/account/rate-limits to learn more.',
param: null
},
code: 'rate_limit_exceeded',
param: null,
type: 'tokens'
}
Node.js v22.14.0
$ codex --version
0.1.2505140839
Still rate_limits_exceeded on version 0.1.2505172129 with model gpt-4.1.
Temporary fix I found for this that works is that you can ask codex or make yourself a simple script that saves user and codex assistant prompts and responses to log files, and when it crashes and you have to start a new session give the log file to codex so it knows where you left off.
I requested to run it every time I send a prompt and every time codex gave me an answer.
Thank you for the feedback! Please try again on the latest version of Codex CLI. If the issue persists, we'd be happy to take a look at a PR to the codex-rs/ implementation. For more details, see our update: #1174.
Activity
Fredrik-C commentedon Apr 28, 2025
It is sad that this is still an issue. Should be priority one to fix the crashes since you loose all context and wasted tokens.
#137
#157
tibo-openai commentedon Apr 29, 2025
The version number above indicates that you are running an old version. This was fixed a while ago, please ensure that you are running the latest version here: https://github.com/openai/codex/blob/main/CHANGELOG.md#012504251709
You should see
e-e-e commentedon Apr 29, 2025
I am still getting this issue in version
0.1.2504221401which supposedly includes the commit (#506) that was to fix these issues.For example:
When I look into the logs I see it was because I exceeded quota with the offending request.
This is really bad UX as it blows away context and costs the user money without giving value.
I am kinda shocked by the state of this tool. It feels very broken.
andrewleech commentedon Apr 30, 2025
This relates to pretty much any "failed" api request, they all crash out.
Error 400 / 500 / etc should all be handled similarly to rate limiting, retry with backoff.
IMO The only one that should likely be fail fast is an invalid key (as opposed to a rate limited key)
Many other API error responses are fleeting, either their server needs you to retry because they're flooded, or the LLM needs to retry with slightly different request/response to come up with a working message.
rivershah commentedon May 4, 2025
Still there in:
tralston commentedon May 15, 2025
Still crashing (v0.1.2505140839):
mdave752 commentedon Jun 28, 2025
Still rate_limits_exceeded on version 0.1.2505172129 with model gpt-4.1.
Temporary fix I found for this that works is that you can ask codex or make yourself a simple script that saves user and codex assistant prompts and responses to log files, and when it crashes and you have to start a new session give the log file to codex so it knows where you left off.
I requested to run it every time I send a prompt and every time codex gave me an answer.
This is the script codex made for my project:
rivershah commentedon Jun 29, 2025
How is this issue still open and not fixed?
codex-maintainers commentedon Aug 7, 2025
Thank you for the feedback! Please try again on the latest version of Codex CLI. If the issue persists, we'd be happy to take a look at a PR to the
codex-rs/implementation. For more details, see our update: #1174.