bug: non-openai model provider stops responding after a few turns
What version of Codex is running?
v0.1.2504221401
Which model were you using?
gemini-2.5-pro-preview-03-25
What platform is your computer?
linux rhel8
What steps can reproduce the bug?
When I startup codex, and use gemini I can occasionally get it to go for a few turns. Usually it will only respond once or twice and then it will freeze.
example:
codex
╭──────────────────────────────────────────────────────────────╮
│ ● OpenAI Codex (research preview) v0.1.2504221401 │
╰──────────────────────────────────────────────────────────────╯
╭──────────────────────────────────────────────────────────────╮
│ localhost session: 76706eb1dadd431696d746907841195a │
│ ↳ workdir: ~ │
│ ↳ model: gemini-2.5-pro-preview-03-25 │
│ ↳ provider: Gemini │
│ ↳ approval: suggest │
╰──────────────────────────────────────────────────────────────╯
user
what is in the current dir?
command
$ ls -al
command.stdout (code: 0, duration: 0.1s)
total 9724568
drwxr-xr-x 111 xxxx xxx 28672 Apr 22 19:38 .
drwxr-xr-x 4 xxxx xxxxx 0 Apr 22 17:52 ..
-rw-r--r-- 1 xxxx xxx 1733 Nov 19 14:20 000.sdf
... (152 more lines)
user
did you find anything good?
user
hi
user
hellow
╭─────────────────────────────────────────────────────────────────────╮
│ │
╰─────────────────────────────────────────────────────────────────────╯
send q or ctrl+c to exit | send "/clear" to reset | send "/help"
for commands | press enter to send | shift+enter for new line — 98%
context left
In the example above you can just keep putting chats in with many different requests and no responses come. I try then to disable the response storage and run, but codex immediately crashes with the following stack trace:
╭──────────────────────────────────────────────────────────────╮
│ ● OpenAI Codex (research preview) v0.1.2504221401 │
╰──────────────────────────────────────────────────────────────╯
╭──────────────────────────────────────────────────────────────╮
│ localhost session: 8b534ba2dfd146a4bc44cca053aec691 │
│ ↳ workdir: ~ │
│ ↳ model: gemini-2.5-pro-preview-03-25 │
│ ↳ provider: Gemini │
│ ↳ approval: suggest │
╰──────────────────────────────────────────────────────────────╯
user
what is in the current dir?
command
$ ls -A
╭─────────────────────────────────────────────────────────────────────╮
│( ● ) 2s Thinking │
╰─────────────────────────────────────────────────────────────────────╯
send q or ctrl+c to exit | send "/clear" to reset | send "/help"
for commands | press enter to send | shift+enter for new line —
100% context left
file:///home/grahat12/.nvm/versions/node/v22.14.0/lib/node_modules/@openai/codex/dist/cli.js:373);return Vn.default.createElement(we,{flexDirection:"column",gap:1},Vn.default.createElement(q,{color:"magenta",bold:!0},"command.stdout"," ",Vn.default.createElement(q,{dimColor:!0},o?(${o}):"")),Vn.default.createElement(q,{dimColor:!0},d))}function BOe({message:e}){return Vn.default.createElement(q,null,JSON.stringify(e,null,2))}function Kne({children:e,...t}){let r=JA(),n=Vn.default.useMemo(()=>(rq({renderer:new zne({...t,width:r.columns})}),nq(e,{async:!1}).trim()),[e,r.columns,r.rows]);return Vn.default.createElement(q,null,n)}m();var An=Oe(ut(),1);import kOe from"node:path";var FOe=({terminalRows:e,version:t,PWD:r,model:n,provider:a="openai",approvalPolicy:i,colorsByPolicy:o,agent:c,initialImagePaths:d,flexModeEnabled:f=!1})=>An.default.createElement(An.default.Fragment,null,e<10?An.default.createElement(q,null,"\u25CF Codex v",t," - ",r," - ",n," (",a,") -"," ",An.default.createElement(q,{color:o[i]},i),f?" - flex-mode":""):An.default.createElement(An.default.Fragment,null,An.default.createElement(we,{borderStyle:"round",paddingX:1,width:64},An.default.createElement(q,null,"\u25CF OpenAI ",An.default.createElement(q,{bold:!0},"Codex")," ",An.default.createElement(q,{dimColor:!0},"(research preview) ",An.default.createElement(q,{color:"blueBright"},"v",t)))),An.default.createElement(we,{borderStyle:"round",borderColor:"gray",paddingX:1,width:64,flexDirection:"column"},An.default.createElement(q,null,"localhost ",An.default.createElement(q,{dimColor:!0},"session:")," ",An.default.createElement(q,{color:"magentaBright",dimColor:!0},c?.sessionId??"<no-session>")),An.default.createElement(q,{dimColor:!0},An.default.createElement(q,{color:"blueBright"},"\u21B3")," workdir: ",An.default.createElement(q,{bold:!0},r)),An.default.createElement(q,{dimColor:!0},An.default.createElement(q,{color:"blueBright"},"\u21B3")," model: ",An.default.createElement(q,{bold:!0},n)),An.default.createElement(q,{dimColor:!0},An.default.createElement(q,{color:"blueBright"},"\u21B3")," provider:"," ",An.default.createElement(q,{bold:!0},a)),An.default.createElement(q,{dimColor:!0},An.default.createElement(q,{color:"blueBright"},"\u21B3")," approval:"," ",An.default.createElement(q,{bold:!0,color:o[i],dimColor:!0},i)),f&&An.default.createElement(q,{dimColor:!0},An.default.createElement(q,{color:"blueBright"},"\u21B3")," flex-mode:"," ",An.default.createElement(q,{bold:!0},"enabled")),d?.map((A,h)=>An.default.createElement(q,{key:A??h,color:"gray"},An.default.createElement(q,{color:"blueBright"},"\u21B3")," image:"," ",An.default.createElement(q,{bold:!0},kOe.basename(A))))))),jne=FOe;var Hp=Oe(ut(),1),LOe=({batch:e,headerProps:t,loading:r,thinkingSeconds:n,fullStdout:a,setOverlayMode:i})=>{let o=(0,Hp.useMemo)(()=>e.map(({item:c})=>c),[e]);return Hp.default.createElement(we,{flexDirection:"column"},Hp.default.createElement(gT,{items:["header",...o]},(c,d)=>{if(c==="header")return Hp.default.createElement(jne,{key:"header",...t});let f=c;return f.summary?.length===0?null:Hp.default.createElement(we,{key:${f.id}-${d},flexDirection:"column",marginLeft:f.type==="message"&&f.role==="user"?0:4,marginTop:f.type==="message"&&f.role==="user"?0:1},Hp.default.createElement($C,{item:f,fullStdout:a,setOverlayMode:i}))}))},Xne=Hp.default.memo(LOe);m();var Og=Oe(ut(),1);function Jne(){let[e,t]=(0,Og.useState)(null),r=(0,Og.useRef)([]),n=(0,Og.useCallback)(()=>{let o=r.current.shift()??null;t(o)},[]),a=(0,Og.useCallback)((o,c)=>new Promise(d=>{let f=r.current.length===0;r.current.push({prompt:o,resolve:d,explanation:c}),f&&n()}),[n]),i=o=>{e&&(e.resolve(o),n())};return{confirmationPrompt:e?.prompt,explanation:e?.explanation,requestConfirmation:a,submitConfirmation:i}}m();dd();sc();m();var sO=new Map;function KC(e="msg"){return${e}_${Math.random().toString(36).substr(2,9)}}function Zne(e){if(typeof e=="string")return{role:"user",content:e};let t=e;if(t.type==="message"){let r=Array.isArray(t.content)?t.content.filter(n=>typeof n=="object"&&n.type==="input_text").map(n=>typeof n=="object"&&"text"in n&&n.text||"").join(""):"";return{role:t.role,content:r}}else if(t.type==="function_call_output")return{role:"tool",tool_call_id:t.call_id,content:t.output};throw new Error(Unsupported input item type: ${t.type})}function eae(e){let t=[];if(e.previous_response_id){let a=sO.get(e.previous_response_id);if(!a)throw new Error(Previous response not found: ${e.previous_response_id});t=a.messages}let r=Array.isArray(e.input)?e.input.map(Zne):[Zne(e.input)],n=[...t,...r];return e.instructions&&n[0]?.role!=="system"&&n[0]?.role!=="developer"?[{role:"system",content:e.instructions},...n]:n}function tae(e){return e?.filter(t=>t.type==="function").map(t=>({type:"function",function:{name:t.name,description:t.description||void 0,parameters:t.parameters}}))}async function lO(e,t){return t.stream?POe(e,t):MOe(e,t)}async function MOe(e,t){let r=eae(t),n=tae(t.tools),a=t.tools?.some(o=>o.type==="function"&&o.name==="web_search")?{}:void 0,i={model:t.model,messages:r,tools:n,web_search_options:a,temperature:t.temperature,top_p:t.top_p,tool_choice:t.tool_choice==="auto"?"auto":t.tool_choice,user:t.user,metadata:t.metadata};try{let o=await e.chat.completions.create(i);if(!("choices"in o)||o.choices.length===0)throw new Error("No choices in chat completion response");let c=o.choices?.[0]?.message;if(!c)throw new Error("No assistant message in chat completion response");let d=KC("resp"),f=KC("msg"),A=[],h=c.tool_calls&&c.tool_calls.length>0;if(h&&c.tool_calls)for(let b of c.tool_calls)b.type==="function"&&A.push({type:"function_call",call_id:b.id,name:b.function.name,arguments:b.function.arguments});c.content&&A.push({type:"output_text",text:c.content,annotations:[]});let S={id:d,object:"response",created_at:Math.floor(Date.now()/1e3),status:h?"requires_action":"completed",error:null,incomplete_details:null,instructions:null,max_output_tokens:null,model:o.model,output:[{type:"message",id:f,status:"completed",role:"assistant",content:A}],parallel_tool_calls:t.parallel_tool_calls??!1,previous_response_id:t.previous_response_id??null,reasoning:null,temperature:t.temperature??1,text:{format:{type:"text"}},tool_choice:t.tool_choice??"auto",tools:t.tools??[],top_p:t.top_p??1,truncation:t.truncation??"disabled",usage:o.usage?{input_tokens:o.usage.prompt_tokens,input_tokens_details:{cached_tokens:0},output_tokens:o.usage.completion_tokens,output_tokens_details:{reasoning_tokens:0},total_tokens:o.usage.total_tokens}:void 0,user:t.user??void 0,metadata:t.metadata??{},output_text:""};h&&c.tool_calls&&(S.required_action={type:"submit_tool_outputs",submit_tool_outputs:{tool_calls:c.tool_calls.map(b=>({id:b.id,type:b.type,function:{name:b.function.name,arguments:b.function.arguments}}))}});let C=[...r,c];return sO.set(d,{previous_response_id:t.previous_response_id??null,messages:C}),S}catch(o){let c=o instanceof Error?o.message:String(o);throw new Error(Failed to process chat completion: ${c})}}async function*POe(e,t){let r=eae(t),n=tae(t.tools),a=t.tools?.some(o=>o.type==="function"&&o.name==="web_search")?{}:void 0,i={model:t.model,messages:r,tools:n,web_search_options:a,temperature:t.temperature??1,top_p:t.top_p??1,tool_choice:t.tool_choice==="auto"?"auto":t.tool_choice,stream:!0,user:t.user,metadata:t.metadata};try{let o=await e.chat.completions.create(i),c=KC("resp"),d=KC("msg"),f=!1,A="",h=new Map,S=null,C=[],b={id:c,object:"response",created_at:Math.floor(Date.now()/1e3),status:"in_progress",model:t.model,output:[],error:null,incomplete_details:null,instructions:null,max_output_tokens:null,parallel_tool_calls:!0,previous_response_id:t.previous_response_id??null,reasoning:null,temperature:t.temperature??1,text:{format:{type:"text"}},tool_choice:t.tool_choice??"auto",tools:t.tools??[],top_p:t.top_p??1,truncation:t.truncation??"disabled",usage:void 0,user:t.user??void 0,metadata:t.metadata??{},output_text:""};yield{type:"response.created",response:b},yield{type:"response.in_progress",response:b};let w=!1;for await(let I of o){let O=I.choices[0];if(!O)continue;if(!w&&("tool_calls"in O.delta&&O.delta.tool_calls||O.finish_reason==="tool_calls")&&(w=!0),I.usage&&(S={prompt_tokens:I.usage.prompt_tokens,completion_tokens:I.usage.completion_tokens,total_tokens:I.usage.total_tokens,input_tokens:I.usage.prompt_tokens,input_tokens_details:{cached_tokens:0},output_tokens:I.usage.completion_tokens,output_tokens_details:{reasoning_tokens:0}}),w){for(let Y of O.delta.tool_calls||[]){let re=Y.index,W=f?re+1:re;if(!h.has(re)){let Z=Y.id||KC("call"),V=Y.function?.name||"";yield{type:"response.output_item.added",item:{type:"function_call",id:d,status:"in_progress",call_id:Z,name:V,arguments:""},output_index:0},h.set(re,{id:Z,name:V,arguments:""})}if(Y.function?.arguments){let Z=h.get(re);Z&&(Z.arguments+=Y.function.arguments,yield{type:"response.function_call_arguments.delta",item_id:d,output_index:0,content_index:W,delta:Y.function.arguments})}}if(O.finish_reason==="tool_calls")for(let[Y,re]of h){let W={type:"function_call",id:d,status:"completed",call_id:re.id,name:re.name,arguments:re.arguments};yield{type:"response.function_call_arguments.done",item_id:d,output_index:Y,content_index:f?Y+1:Y,arguments:re.arguments},yield{type:"response.output_item.done",output_index:Y,item:W},C.push(W)}else continue}else if(f||(yield{type:"response.content_part.added",item_id:d,output_index:0,content_index:0,part:{type:"output_text",text:"",annotations:[]}},f=!0),O.delta.content?.length&&(yield{type:"response.output_text.delta",item_id:d,output_index:0,content_index:0,delta:O.delta.content},A+=O.delta.content),O.finish_reason){yield{type:"response.output_text.done",item_id:d,output_index:0,content_index:0,text:A},yield{type:"response.content_part.done",item_id:d,output_index:0,content_index:0,part:{type:"output_text",text:A,annotations:[]}};let Y={type:"message",id:d,status:"completed",role:"assistant",content:[{type:"output_text",text:A,annotations:[]}]};yield{type:"response.output_item.done",output_index:0,item:Y},C.push(Y)}else continue;let B={id:c,object:"response",created_at:b.created_at||Math.floor(Date.now()/1e3),status:"completed",error:null,incomplete_details:null,instructions:null,max_output_tokens:null,model:I.model||t.model,output:C,parallel_tool_calls:!0,previous_response_id:t.previous_response_id??null,reasoning:null,temperature:t.temperature??1,text:{format:{type:"text"}},tool_choice:t.tool_choice??"auto",tools:t.tools??[],top_p:t.top_p??1,truncation:t.truncation??"disabled",usage:S,user:t.user??void 0,metadata:t.metadata??{},output_text:""},G={role:"assistant",content:A||null};if(h.size>0){let Y=Array.from(h.values()).map(re=>({id:re.id,type:"function",function:{name:re.name,arguments:re.arguments}}));G.tool_calls=Y}let U=[...r,G];sO.set(c,{previous_response_id:t.previous_response_id??null,messages:U}),yield{type:"response.completed",response:B}}}catch(o){yield{type:"error",code:o instanceof Error&&"code"in o?o.code:"unknown",message:o instanceof Error?o.message:String(o),param:null}}}pg();m();m();m();import l4 from"fs";import rae from"path";var Wa=class extends Error{},uO=class{current_files;lines;index=0;patch={actions:{}};fuzz=0;constructor(t,r){this.current_files=t,this.lines=r}is_done(t){return!!(this.index>=this.lines.length||t&&t.some(r=>this.lines[this.index].startsWith(r.trim())))}startswith(t){return(Array.isArray(t)?t:[t]).some(n=>this.lines[this.index].startsWith(n))}read_str(t="",r=!1){if(this.index>=this.lines.length)throw new Wa(Index: ${this.index} >= ${this.lines.length});if(this.lines[this.index].startsWith(t)){let n=r?this.lines[this.index]:this.lines[this.index].slice(t.length);return this.index+=1,n??""}return""}parse(){for(;!this.is_done([gg]);){let t=this.read_str(hg);if(t){if(this.patch.actions[t])throw new Wa(Update File Error: Duplicate Path: ${t});let r=this.read_str(bY);if(!(t in this.current_files))throw new Wa(Update File Error: Missing File: ${t});let n=this.current_files[t],a=this.parse_update_file(n??"");a.move_path=r||void 0,this.patch.actions[t]=a;continue}if(t=this.read_str(Ag),t){if(this.patch.actions[t])throw new Wa(Delete File Error: Duplicate Path: ${t});if(!(t in this.current_files))throw new Wa(Delete File Error: Missing File: ${t});this.patch.actions[t]={type:"delete",chunks:[]};continue}if(t=this.read_str(_g),t){if(this.patch.actions[t])throw new Wa(Add File Error: Duplicate Path: ${t});if(t in this.current_files)throw new Wa(Add File Error: File already exists: ${t});this.patch.actions[t]=this.parse_add_file();continue}throw new Wa(Unknown Line: ${this.lines[this.index]})}if(!this.startswith(gg.trim()))throw new Wa("Missing End Patch");this.index+=1}parse_update_file(t){let r={type:"update",chunks:[]},n=t.split(
Error: Unsupported input item type: function_call
at Zne (file:///home/xxxx/.nvm/versions/node/v22.14.0/lib/node_modules/@openai/codex/dist/cli.js:373:4203)
at Array.map (<anonymous>)
at eae (file:///home/xxxx/.nvm/versions/node/v22.14.0/lib/node_modules/@openai/codex/dist/cli.js:373:4474)
at POe (file:///home/xxxx/.nvm/versions/node/v22.14.0/lib/node_modules/@openai/codex/dist/cli.js:373:6987)
at POe.next (<anonymous>)
at fE.run (file:///home/xxxx/.nvm/versions/node/v22.14.0/lib/node_modules/@openai/codex/dist/cli.js:492:2763)
at process.processTicksAndRejections (node:internal/process/task_queues:105:5)
Node.js v22.14.0
What is the expected behavior?
Normal back and forth with the agent and no crash.
What do you see instead?
See above for stack trace and output.
Additional information
Is this expected behavior? I admit it isn't an openai model, but I am curious what is causing the crash. I have set the GEMINI_API_KEY and can get it to work for a few turns. Sometimes it helps to delete my ~/.codex dir but I haven't found a consistent pattern for improving things.
I do also notice that when successful tool calls are chained things go smoothly, but if you get a command without output it will often get to the point where it doesn't respond to any input:
command
$ qstat -s r
command.stdout (code: 0, duration: 2.6s)
user
you need to use qstat -u /*
╭─────────────────────────────────────────────────────────────────────╮
│ │
╰─────────────────────────────────────────────────────────────────────╯
send q or ctrl+c to exit | send "/clear" to reset | send "/help"
for commands | press enter to send | shift+enter for new line — 97%
context left
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗