claude-code icon indicating copy to clipboard operation
claude-code copied to clipboard

[BUG] Claude Code crashes with unhandled EPERM when killing shell running as different user

Open HFTrader opened this issue 3 weeks ago • 1 comments

Preflight Checklist

  • [x] I have searched existing issues and this hasn't been reported yet
  • [x] This is a single bug report (please file separate reports for different bugs)
  • [x] I am using the latest version of Claude Code

What's Wrong?

When using Kill Shell to terminate a background shell that spawned a process running as a different user (e.g., sudo -u postgres psql), Claude Code crashes instead of handling the error gracefully.

Application crashes with unhandled exception and React/Ink stack trace

What Should Happen?

Error message like "Cannot kill shell: permission denied"

Error Messages/Logs

● The COUNT query on the fixings table is taking a very long time (it's a 777GB database). Let me kill that query and just verify the database is working with a simpler check:

● Kill Shell(Kill shell: ae1652)
  ⎿  Shell ae1652 killed

* Bootstrapping… (esc to interrupt · ctrl+t to hide todos · 12m 13s · ↑ 1.2k tokens)
  ⎿  ☒ Stop PostgreSQL clusters
     ☒ Drop the empty PostgreSQL 14 cluster on /var/lib
     ☒ Run pg_upgradecluster with --link to migrate v12 to v14 under /mnt/data
     ☒ Verify etf database is accessible on upgraded cluster
     ☐ Drop old PostgreSQL 12 cluster

────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
────
> 
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
────
  ? for shortcuts
790 | `).slice(1):void 0,A=$?bfI.parseLine($[0]):void 0,L=kfI(A?.file),I,D=0;if(L&&A?.line&&ieH.existsSync(L)){let B=ieH.readFileSync(L,"utf8");if(I=RfI(B,A.line),I)for(let{line:G}of 
I)D=Math.max(D,String(G).length)}return 
MQ.default.createElement(g2,{flexDirection:"column",padding:1},MQ.default.createElement(g2,null,MQ.default.createElement(V,{backgroundColor:"error",color:"text"}," ","ERROR"," 
"),MQ.default.createElement(V,null," ",H.message)),A&&L&&MQ.default.createElement(g2,{marginTop:1},MQ.default.createElement(V,{dimColor:!0},L,":",A.line,":",A.column)),A&&I&&MQ.default
.createElement(g2,{marginTop:1,flexDirection:"column"},I.map(({line:B,value:G})=>MQ.default.createElement(g2,{key:B},MQ.default.createElement(g2,{width:D+1},MQ.default.createElement(V,
{dimColor:B!==A.line,backgroundColor:B===A.line?"error":void 0,color:B===A.line?"text":void 0},String(B).padStart(D," 
"),":")),MQ.default.createElement(V,{key:B,backgroundColor:B===A.line?"error":void 0,color:B===A.line?"text":void 0}," "+G)))),H.stack&&MQ.defaul | ... truncated 
791 | `).slice(1).map((B)=>{let G=bfI.parseLine(B);if(!G)return MQ.default.createElement(g2,{key:B},MQ.default.createElement(V,{dimColor:!0},"- 
"),MQ.default.createElement(V,{dimColor:!0,bold:!0},B));return MQ.default.createElement(g2,{key:B},MQ.default.createElement(V,{dimColor:!0},"- 
"),MQ.default.createElement(V,{dimColor:!0,bold:!0},G.function),MQ.default.createElement(V,{dimColor:!0}," ","(",kfI(G.file)??"",":",G.line,":",G.column,")"))})))}var 
ieH,yl$,MQ,_l$,kfI=(H)=>{return H?.replace(`file://${yl$.cwd()}/`,"")},bfI;var 
hfI=f(()=>{_fI();z2H();leH();ieH=N(require("fs")),yl$=require("process"),MQ=N(EH(),1),_l$=N(TfI(),1),bfI=new 
_l$.default({cwd:yl$.cwd(),internals:_l$.default.nodeInternals()})});function LA1(H){return{name:"",fn:!1,ctrl:!1,meta:!1,shift:!1,option:!1,sequence:H,raw:H,isPasted:!0}}function 
BA1(H){if(gfI.Buffer.isBuffer(H))if(H[0]>127&&H[1]===void 0)return H[0]-=128,"\x1B"+String(H);else return String(H);else if(H!==void 0&&typeof H!=="string")return String(H);else 
if(!H)return"";else return H}f | ... truncated 
792 | `)A.name="enter";else if(H==="\t")A.name="tab";else if(H==="\b"||H==="\x1B\b")A.name="backspace",A.meta=H.charAt(0)==="\x1B";else 
if(H==="\x7F"||H==="\x1B\x7F")A.name="backspace",A.meta=H.charAt(0)==="\x1B";else if(H==="\x1B"||H==="\x1B\x1B")A.name="escape",A.meta=H.length===2;else if(H===" "||H==="\x1B 
")A.name="space",A.meta=H.length===2;else if(H==="\x1F")A.name="_",A.ctrl=!0;else if(H<="\x1A"&&H.length===1)A.name=String.fromCharCode(H.charCodeAt(0)+97-1),A.ctrl=!0;else 
if(H.length===1&&H>="0"&&H<="9")A.name="number";else if(H.length===1&&H>="a"&&H<="z")A.name=H;else if(H.length===1&&H>="A"&&H<="Z")A.name=H.toLowerCase(),A.shift=!0;else 
if($=HA1.exec(H))A.meta=!0,A.shift=/^[A-Z]$/.test($[1]);else if($=$A1.exec(H)){let L=[...H];if(L[0]==="\x1B"&&L[1]==="\x1B")A.option=!0;let 
I=[$[1],$[2],$[4],$[6]].filter(Boolean).join(""),D=($[3]||$[5]||1)-1;A.ctrl=!!(D&4),A.meta=!!(D&10),A.shift=!!(D&1),A.code=I,A.name=dfI[I],A.shift=GA1(I)||A.shift,A.ctrl=EA1(I)||A.ctrl
}if(A.raw==="\x1Bb")A.meta=!0,A.name="left";else if( | ... truncated 
793 | Read about how to prevent this error on https://github.com/vadimdemedes/ink/#israwmodesupported`);else throw Error(`Raw mode is not supported on the stdin provided to Ink.
794 | Read about how to prevent this error on https://github.com/vadimdemedes/ink/#israwmodesupported`);if($.setEncoding("utf8"),H){if(this.rawModeEnabledCount===0)$.ref(),$.setRawMode
(!0),$.addListener("readable",this.handleReadable),this.props.stdout.write("\x1B[?2004h");this.rawModeEnabledCount++;return}if(--this.rawModeEnabledCount===0)this.props.stdout.write("\
x1B[?2004l"),$.setRawMode(!1),$.removeListener("readable",this.handleReadable),$.unref()};flushIncomplete=()=>{if(this.incompleteEscapeTimer=null,!this.keyParseState.incomplete)return;
this.processInput(null)};processInput=(H)=>{let[$,A]=mfI(this.keyParseState,H);this.keyParseState=A;for(let L of $){this.handleInput(L.sequence);let I=new 
oeH(L);this.internal_eventEmitter.emit("input",I)}if(this.keyParseState.incomplete){if(this.incompleteEscapeTimer)clearTimeout(this.incompleteEscapeTimer);this.incompleteEscapeTimer=se
tTimeout(this.flushIncomplete,this.keyParseState.mode==="IN_PASTE"?this.PASTE_TIMEOUT:this.NORMAL_TIMEOUT)}};handleReadable=()=>{let H;whil | ... truncated 
795 | `.repeat(H))}var DVI;var BVI=f(()=>{DVI=N(EH(),1)});var nD1;var GVI=f(()=>{z2H();nD1=N(EH(),1)});function fH$({state:H,percentage:$}){return 
EVI.default.createElement("ink-progress",{state:H,percentage:$})}var EVI;var MVI=f(()=>{EVI=N(EH(),1)});var XVI,rD1=()=>XVI.useContext(geH),Ec;var 
FH$=f(()=>{zl$();XVI=N(EH(),1),Ec=rD1});var 
Ei$,aD1=(H,$={})=>{let{stdin:A,setRawMode:L,internal_exitOnCtrlC:I,internal_eventEmitter:D}=Ec();Ei$.useEffect(()=>{if($.isActive===!1)return;return 
L(!0),()=>{L(!1)}},[$.isActive,L]),Ei$.useEffect(()=>{if($.isActive===!1)return;let B=(G)=>{let{input:E,key:M}=G;if(!(E==="c"&&M.ctrl)||!I)$c.batchedUpdates(()=>{H(E,M,G)})};return 
D?.on("input",B),()=>{D?.removeListener("input",B)}},[$.isActive,A,I,H])},_$;var JVI=f(()=>{sp$();FH$();Ei$=N(EH(),1),_$=aD1});var WVI,sD1=()=>WVI.useContext(veH),Mi$;var 
KVI=f(()=>{Pl$();WVI=N(EH(),1),Mi$=sD1});var Xi$;var QVI=f(()=>{meH();FH$();Xi$=N(EH(),1)});var oD1;var fVI=f(()=>{meH();oD1=N(EH(),1)});var 
tD1=(H)=>({width:H.yogaNode?.getComputedWidth()??0 | ... truncated 

SystemError: kill() failed: EPERM: Operation not permitted
 syscall: "kill",
   errno: 1,
    code: "EPERM"

✢ Bootstrapping… (esc to interrupt · ctrl+t to hide todos · 12m 13s · ↑ 1.2k tokens)
  ⎿  ☒ Stop PostgreSQL clusters
     ☒ Drop the empty PostgreSQL 14 cluster on /var/lib
     ☒ Run pg_upgradecluster with --link to migrate v12 to v14 under /mnt/data
     ☒ Verify etf database is accessible on upgraded cluster
     ☐ Drop old PostgreSQL 12 cluster

Steps to Reproduce

  1. Start Claude Code
  2. Run a command as a different user in the background: sudo -u postgres psql -c "SELECT pg_sleep(60);"
  3. (or any long-running command with sudo -u <other_user>)
  4. While it's running, use /tasks to find the shell ID
  5. Use the Kill Shell tool to terminate that shell
  6. Result: Claude Code crashes with EPERM: Operation not permitted

The key condition is that the shell must have spawned a child process running as a different user than the one running Claude Code.

Claude Model

Opus

Is this a regression?

I don't know

Last Working Version

No response

Claude Code Version

2.0.59 (Claude Code)

Platform

Anthropic API

Operating System

Ubuntu/Debian Linux

Terminal/Shell

Xterm

Additional Information

No response

HFTrader avatar Dec 06 '25 00:12 HFTrader