Shell Integration Warning when using MiMo: Root Cause Analysis and Fix
Environment
- AI Model: MiMo 2.5 Pro (Xiaomi) — long Chain-of-Thought reasoning causes extended wait times between terminal commands, and tendency to maintain long sessions makes these bugs especially prominent
- Zoo Code: v3.65.100202 (
zoocodeorganization.zoo-code) - OS: Windows 11, PowerShell 5.1
- Target File:
dist/extension.js (15,442,677 bytes) - Date: 2026-06-28
Summary of Bugs Found
| # | Bug | Severity | User Experience | Root Cause Function |
|---|
| 1 | Dead terminal reuse infinite loop | 🔴 Critical | Command execution permanently impossible (10+ consecutive failures) | getOrCreateTerminal() |
| 2 | Missing shellPath fallback | 🔴 Critical | PowerShell cmdlets don't execute on Windows | Ln constructor |
| 3 | execa provider cmd.exe fallback | 🔴 Critical | git commit and other commands with quotes fail | xit.run() |
| 4 | Intermittent command failures (3 causes) | 🟠 High | Same command alternates between success/failure (~35% failure rate) | getOrCreateTerminal(), catch block, Olr.execute() |
| 5 | Missing customCwd type validation | 🟠 High | Terminal state permanently corrupted, all commands fail | CFi() |
Bug 1: Dead Terminal Reuse Infinite Loop
Symptom
When executing commands via execute_command, if the terminal process is dead (user closed the panel, shell integration initialization failed, etc.), Zoo Code enters an infinite loop reusing the same dead terminal.
Command attempt → Terminal process already dead → ShellIntegrationError
→ Error handler retries with same taskId → getOrCreateTerminal returns same dead terminal
→ ShellIntegrationError again → infinite loop
Actual error message:
Command failed to execute in terminal due to a shell integration error.
VS Code UI warning:
Your command is being executed without VSCode terminal shell integration.
Real reproduction timeline (23 attempts in 16 minutes, 15 failures — 35% success rate):
[05:22:47] python analyze_script.py → ✅ success
[05:23:07] powershell Get-ChildItem → ❌ "shell integration error"
[05:23:25] python analyze_script.py → ❌ "shell integration error"
[05:23:32] python analyze_script.py → ❌ "shell integration error"
... (10 consecutive failures) ...
[05:24:49] python analyze_script.py → ✅ success (new terminal assigned)
[05:25:11] python -c "..." → ❌ "shell integration error"
[05:25:19] python -c "..." → ✅ success
[05:25:26] python -c "..." → ❌ "shell integration error"
Key observation: success/failure occurs regardless of command content. echo "test" succeeds, then python -c "print('test')" fails immediately after.
Root Cause Code (extension.js, getOrCreateTerminal(), offset ~14,921,404)
Call chain:
Olr.execute() [execute_command tool handler]
└─ try { CFi(r, w) } [terminal command execution]
├─ Fh.getOrCreateTerminal(c, t.taskId, N) [find or create terminal]
└─ Y.runCommand(r, Q) [execute command in terminal]
└─ onNoShellIntegration → new Yq() [ShellIntegrationError thrown]
└─ catch(E)
└─ FNl(E) → true → CFi(r, {...w, terminalShellIntegrationDisabled:!0})
⚠️ Same dead terminal returned → infinite loop
getOrCreateTerminal()'s find() searches by taskId + provider + reuseKey + cwd, but dead terminals also satisfy all these conditions. There's no isClosed() check, so dead terminals are returned as-is.
// ❌ Original code — getOrCreateTerminal() (offset ~14,921,404)staticasyncgetOrCreateTerminal(e,r,a="vscode"){leto=this.getAllTerminals(),s=a==="vscode" ? Ln.getReuseKey() : a,n;returnr&&(n=o.find(l=>{if(l.busy||l.taskId!==r||l.provider!==a||l.reuseKey!==s)return!1;letc=l.getCurrentWorkingDirectory();returnc ? jo(Rq.Uri.file(e).fsPath,c) : !1})),n||(n=o.find(l=>{if(l.busy||l.provider!==a||l.reuseKey!==s)return!1;letc=l.getCurrentWorkingDirectory();returnc ? jo(Rq.Uri.file(e).fsPath,c) : !1})),n||(n=this.createTerminal(e,a)),n.taskId=r,n}The error handler also doesn't create a new terminal on retry:
// ❌ Original code — catch block (offset ~15,077,884)catch(E){if(r.supersedePendingAsk(),FNl(E)){letm={executionId: v,status: "fallback"};x?.postMessageToWebview({type: "commandExecutionStatus",text: JSON.stringify(m)});let[g,y]=awaitCFi(r,{...w,terminalShellIntegrationDisabled: !0});// ⚠️ No forceNewTerminal option → getOrCreateTerminal returns same dead terminalg&&(r.didRejectTool=!0),c(y)}}Fix (before/after)
Fix 1/5 — Add 4th parameter to getOrCreateTerminal():
// ✅ After fix — getOrCreateTerminal()staticasyncgetOrCreateTerminal(e,r,a="vscode",__fn=!1){leto=this.getAllTerminals(),s=a==="vscode" ? Ln.getReuseKey() : a,n;return__fn||(// ← When __fn is true, skip find() calls entirelyr&&(n=o.find(l=>{if(l.busy||l.isClosed()||l.taskId!==r||l.provider!==a||l.reuseKey!==s)return!1;// ^^^^^^^^^^ Exclude dead terminalsletc=l.getCurrentWorkingDirectory();returnc ? jo(Rq.Uri.file(e).fsPath,c) : !1})),n||(n=o.find(l=>{if(l.busy||l.isClosed()||l.provider!==a||l.reuseKey!==s)return!1;// ^^^^^^^^^^ Exclude dead terminalsletc=l.getCurrentWorkingDirectory();returnc ? jo(Rq.Uri.file(e).fsPath,c) : !1}))),n||(n=this.createTerminal(e,a)),// ← __fn=true always reaches here → new terminaln.taskId=r,n}Fix 2/5 — Add forceNewTerminal option to CFi() function (offset ~15,078,569):
// ❌ OriginalasyncfunctionCFi(t,{executionId:e,command:r,customCwd:a,terminalShellIntegrationDisabled:o=!0,commandExecutionTimeout:s=0,agentTimeout:n=0}){// ✅ After fixasyncfunctionCFi(t,{executionId:e,command:r,customCwd:a,terminalShellIntegrationDisabled:o=!0,commandExecutionTimeout:s=0,agentTimeout:n=0,forceNewTerminal:__fn=!1}){Fix 3/5 — Forward __fn to getOrCreateTerminal call (offset ~15,080,813):
// ❌ OriginalletY=awaitFh.getOrCreateTerminal(c,t.taskId,N);// ✅ After fixletY=awaitFh.getOrCreateTerminal(c,t.taskId,N,__fn);
Fix 4/5 — Enable forceNewTerminal on error handler retry (offset ~15,078,012):
// ❌ Originallet[g,y]=awaitCFi(r,{...w,terminalShellIntegrationDisabled: !0});// ✅ After fixlet[g,y]=awaitCFi(r,{...w,terminalShellIntegrationDisabled: !0,forceNewTerminal: !0});Fix 5/5 — Include default value in initial options object (offset ~15,077,775):
// ❌ Original
agentTimeout: I};// ✅ After fix
agentTimeout: I,forceNewTerminal: !1};
Bug 2: Missing shellPath Fallback
Symptom
On Windows, when the VS Code terminal profile is set to cmd.exe or no profile exists, Zoo Code doesn't set shellPath when creating a terminal, falling back to VS Code's default (cmd.exe). Since cmd.exe doesn't support shell integration, all commands fail.
Actual error messages:
Command: Test-Path "README.md"
Result: 'Test-Path' is not recognized as an internal or external command, operable program or batch file.
Command: if (Test-Path "README.md") { (Get-Item "README.md").Length }
Result: ")" was unexpected at this time.
Root Cause Code (extension.js, Ln constructor, offset ~13,190,853)
// ❌ Original code — Ln class constructorvarLn=classtextendsmD{terminal;cmdCounter=0;activeShellExecution;constructor(e,r,a){super("vscode",e,a,t.getReuseKey());leto=t.getEnv(),s=newTf.ThemeIcon("rocket");if(r)this.terminal=r;else{letn={cwd: a,name: "Zoo Code",iconPath: s,env: o},l=t.getProfileShell();l?.shellPath&&(// ← When shellPath is missing, this entire block is skippedn.shellPath=l.shellPath,l.shellArgs&&(n.shellArgs=l.shellArgs),console.info(`[Terminal] Creating terminal with profile "${t.getTerminalProfile()}" -> ${l.shellPath}`),l.env&&(n.env={...l.env, ...o})),this.terminal=Tf.window.createTerminal(n)// ⚠️ createTerminal called without n.shellPath set// → VS Code uses cmd.exe (Windows default)// → No shell integration support → all commands fail}}Fix (before/after)
// ✅ After fix — Ln class constructorl?.shellPath// ← Changed to ternary operator
? (// ← Profile has shellPath (preserve existing behavior)n.shellPath=l.shellPath,l.shellArgs&&(n.shellArgs=l.shellArgs),console.info(`[Terminal] Creating terminal with profile "${t.getTerminalProfile()}" -> ${l.shellPath}`),l.env&&(n.env={...l.env, ...o}))
: (// ← No shellPath: explicit fallbackn.shellPath=process.platform==="win32"
? (process.env.SystemRoot||"C:\\Windows")+"\\System32\\WindowsPowerShell\\v1.0\\powershell.exe"
: process.env.SHELL||"/bin/bash",console.info(`[Terminal] No profile shellPath found; using fallback: ${n.shellPath}`)),this.terminal=Tf.window.createTerminal(n)
Bug 3: execa Provider cmd.exe Fallback
Symptom
When the terminal provider is "execa" instead of "vscode", commands like git commit trigger the shell integration warning. Zoo Code AI detects: "The terminal appears to be running cmd.exe".
Root Cause Code (extension.js, xit.run(), offset ~14,916,022)
// ❌ Original code — execa shell path setting
shell: mD.getExecaShellPath()||!0// When getExecaShellPath() is undefined → ||!0 → true// execa with shell:true → Windows COMSPEC → cmd.exe
Fix (before/after)
// ❌ Original
shell: mD.getExecaShellPath()||!0// ✅ After fix
shell: mD.getExecaShellPath()||(process.platform==="win32"
? (process.env.SystemRoot||"C:\\Windows")+"\\System32\\WindowsPowerShell\\v1.0\\powershell.exe"
: process.env.SHELL||"/bin/bash")
Bug 4: Intermittent Command Failures (3 Causes)
Symptom
After fixing the above 3 bugs, command execution still intermittently fails (~35% failure rate). Same command alternates between success and failure regardless of content.
Cause 1: Missing isClosed() check in getOrCreateTerminal()
// ❌ Original — find() without isClosed() checkn=o.find(l=>{if(l.busy||l.taskId!==r|| ...)return!1;// ⚠️ No l.isClosed() check!})// ✅ After fixn=o.find(l=>{if(l.busy||l.isClosed()||l.taskId!==r|| ...)return!1;// ^^^^^^^^^^ Added})Cause 2: Missing retry for non-Yq errors
// ❌ Original — catch blockcatch(E){if(FNl(E)){awaitCFi(r,{...w,forceNewTerminal:!0});}else{// non-Yq error → warning only, no retry!awaitr.say("shell_integration_warning");}}// ✅ After fixcatch(E){if(FNl(E)){awaitCFi(r,{...w,forceNewTerminal:!0});}elseif(!(EinstanceofYq)){// non-Yq error also retries with new terminalawaitCFi(r,{...w,terminalShellIntegrationDisabled:!0,forceNewTerminal:!0});}else{awaitr.say("shell_integration_warning");}}Cause 3: terminalShellIntegrationDisabled default value problem
// ❌ Original — default true forces execa provider{terminalShellIntegrationDisabled:N=!0}=R??{}// ✅ After fix — default false uses vscode provider{terminalShellIntegrationDisabled:N=!1}=R??{}
Bug 5: Missing customCwd Type Validation
Symptom
When customCwd is passed as an Object instead of string, TypeError occurs. Terminal state becomes permanently corrupted — all subsequent commands fail. Cannot recover even by reloading VS Code.
Stack Trace
TypeError: The "path" argument must be of type string. Received an instance of Object
at Object.isAbsolute (node:path:482:5)
at CFi (extension.js:5086:5100)
at Olr.execute (extension.js:5086:4351)
Fix (before/after)
// ❌ Originala ? cV.isAbsolute(a) ? c=a : c=cV.resolve(a) : ...
// ✅ After fixa&&typeofa==="string" ? cV.isAbsolute(a) ? c=a : c=cV.resolve(a) : ...
Impact Analysis: MiMo Model Relevance
These bugs affect all AI models. However, MiMo 2.5 Pro's characteristics make them more frequent and more visible:
- Long Chain-of-Thought: Extended wait times between terminal commands → higher shell integration timeout chance
- Iterative tool calls: Many steps → frequent terminal use → dead terminal accumulation
- Long sessions: 30+ minute sessions → failure rate spikes
GPT-4, Claude, Gemini, and other models experience the same bugs under the same conditions. The root cause is in Zoo Code's code, not the AI model.
Verification Results
Before fix (16 minutes): 23 attempts, 15 failures → 35% success rate
After fix: 10 consecutive commands tested, 9/10 success (90%). The 1 failure is a PowerShell 5.x && syntax limitation, not a Zoo Code bug. Zoo Code related errors: 0.
Official Fix Suggestions (TypeScript)
1. Terminal reuse state check
staticasyncgetOrCreateTerminal(cwd: string,taskId: string,provider: string="vscode",forceNew: boolean=false){constterminals=this.getAllTerminals();letterminal: TerminalWrapper|undefined;if(!forceNew){terminal=terminals.find(t=>{if(t.busy||t.isClosed()||t.taskId!==taskId||t.provider!==provider)returnfalse;// ... cwd matching logic});}if(!terminal)terminal=this.createTerminal(cwd,provider);terminal.taskId=taskId;returnterminal;}2. shellPath fallback chain
constprofile=Terminal.getProfileShell();if(profile?.shellPath){options.shellPath=profile.shellPath;}else{options.shellPath=process.platform==="win32"
? `${process.env.SystemRoot||"C:\\Windows"}\\System32\\WindowsPowerShell\\v1.0\\powershell.exe`
: process.env.SHELL||"/bin/bash";}3. execa provider shell path fallback
shell: ExecaTerminal.getExecaShellPath()||(process.platform==="win32"
? `${process.env.SystemRoot||"C:\\Windows"}\\System32\\WindowsPowerShell\\v1.0\\powershell.exe`
: process.env.SHELL||"/bin/bash")4. Error handler non-Yq error retry
catch(error){task.supersedePendingAsk();if(isShellIntegrationError(error)&&!error.commandSubmitted){// Retry with new terminalconst[rejected,result]=awaitexecuteCommandInTerminal(task,{
...options,terminalShellIntegrationDisabled: true,forceNewTerminal: true,});resolve(result);}elseif(!(errorinstanceofShellIntegrationError)){// Non-Yq errors also retryconst[rejected,result]=awaitexecuteCommandInTerminal(task,{
...options,terminalShellIntegrationDisabled: true,forceNewTerminal: true,});resolve(result);}else{awaittask.say("shell_integration_warning");resolve("Command failed...");}}5. customCwd type validation
constcwd=customCwd&&typeofcustomCwd==="string"
? (path.isAbsolute(customCwd) ? customCwd : path.resolve(customCwd))
: defaultCwd;
Shell Integration Warning when using MiMo: Root Cause Analysis and Fix
Environment
zoocodeorganization.zoo-code)dist/extension.js(15,442,677 bytes)Summary of Bugs Found
getOrCreateTerminal()Lnconstructorgit commitand other commands with quotes failxit.run()getOrCreateTerminal(), catch block,Olr.execute()CFi()Bug 1: Dead Terminal Reuse Infinite Loop
Symptom
When executing commands via
execute_command, if the terminal process is dead (user closed the panel, shell integration initialization failed, etc.), Zoo Code enters an infinite loop reusing the same dead terminal.Actual error message:
VS Code UI warning:
Real reproduction timeline (23 attempts in 16 minutes, 15 failures — 35% success rate):
Key observation: success/failure occurs regardless of command content.
echo "test"succeeds, thenpython -c "print('test')"fails immediately after.Root Cause Code (extension.js,
getOrCreateTerminal(), offset ~14,921,404)Call chain:
getOrCreateTerminal()'sfind()searches bytaskId + provider + reuseKey + cwd, but dead terminals also satisfy all these conditions. There's noisClosed()check, so dead terminals are returned as-is.The error handler also doesn't create a new terminal on retry:
Fix (before/after)
Fix 1/5 — Add 4th parameter to
getOrCreateTerminal():Fix 2/5 — Add
forceNewTerminaloption toCFi()function (offset ~15,078,569):Fix 3/5 — Forward
__fntogetOrCreateTerminalcall (offset ~15,080,813):Fix 4/5 — Enable
forceNewTerminalon error handler retry (offset ~15,078,012):Fix 5/5 — Include default value in initial options object (offset ~15,077,775):
Bug 2: Missing shellPath Fallback
Symptom
On Windows, when the VS Code terminal profile is set to
cmd.exeor no profile exists, Zoo Code doesn't setshellPathwhen creating a terminal, falling back to VS Code's default (cmd.exe). Sincecmd.exedoesn't support shell integration, all commands fail.Actual error messages:
Root Cause Code (extension.js,
Lnconstructor, offset ~13,190,853)Fix (before/after)
Bug 3: execa Provider cmd.exe Fallback
Symptom
When the terminal provider is
"execa"instead of"vscode", commands likegit committrigger the shell integration warning. Zoo Code AI detects:"The terminal appears to be running cmd.exe".Root Cause Code (extension.js,
xit.run(), offset ~14,916,022)Fix (before/after)
Bug 4: Intermittent Command Failures (3 Causes)
Symptom
After fixing the above 3 bugs, command execution still intermittently fails (~35% failure rate). Same command alternates between success and failure regardless of content.
Cause 1: Missing
isClosed()check ingetOrCreateTerminal()Cause 2: Missing retry for non-Yq errors
Cause 3:
terminalShellIntegrationDisableddefault value problemBug 5: Missing customCwd Type Validation
Symptom
When
customCwdis passed as anObjectinstead ofstring,TypeErroroccurs. Terminal state becomes permanently corrupted — all subsequent commands fail. Cannot recover even by reloading VS Code.Stack Trace
Fix (before/after)
Impact Analysis: MiMo Model Relevance
These bugs affect all AI models. However, MiMo 2.5 Pro's characteristics make them more frequent and more visible:
GPT-4, Claude, Gemini, and other models experience the same bugs under the same conditions. The root cause is in Zoo Code's code, not the AI model.
Verification Results
Before fix (16 minutes): 23 attempts, 15 failures → 35% success rate
After fix: 10 consecutive commands tested, 9/10 success (90%). The 1 failure is a PowerShell 5.x
&&syntax limitation, not a Zoo Code bug. Zoo Code related errors: 0.Official Fix Suggestions (TypeScript)
1. Terminal reuse state check
2. shellPath fallback chain
3. execa provider shell path fallback
4. Error handler non-Yq error retry
5. customCwd type validation