@@ -63,14 +63,25 @@ export abstract class LocalBaseRuntime implements Runtime {
6363 ) ;
6464 }
6565
66- // If niceness is specified on Unix/Linux, spawn nice directly to avoid escaping issues
67- // Windows doesn't have nice command, so just spawn bash directly
66+ // If niceness is specified on Unix/Linux, try to spawn `nice` directly to avoid
67+ // escaping issues. Some minimal environments may not have `nice` on PATH, so
68+ // fall back to running bash directly.
6869 const isWindows = process . platform === "win32" ;
6970 const bashPath = getBashPath ( ) ;
70- const spawnCommand = options . niceness !== undefined && ! isWindows ? "nice" : bashPath ;
71+
72+ const shouldNice = options . niceness !== undefined && ! isWindows ;
73+ const nicePath = shouldNice
74+ ? fs . existsSync ( "/usr/bin/nice" )
75+ ? "/usr/bin/nice"
76+ : fs . existsSync ( "/bin/nice" )
77+ ? "/bin/nice"
78+ : null
79+ : null ;
80+
81+ const spawnCommand = nicePath ?? bashPath ;
7182 const spawnArgs =
72- options . niceness !== undefined && ! isWindows
73- ? [ "-n" , options . niceness . toString ( ) , bashPath , "-c" , command ]
83+ nicePath !== null
84+ ? [ "-n" , options . niceness ! . toString ( ) , bashPath , "-c" , command ]
7485 : [ "-c" , command ] ;
7586
7687 const childProcess = spawn ( spawnCommand , spawnArgs , {
@@ -145,7 +156,12 @@ export abstract class LocalBaseRuntime implements Runtime {
145156 } ) ;
146157 } ) ;
147158
148- const duration = exitCode . then ( ( ) => performance . now ( ) - startTime ) ;
159+ // Always resolve duration even if exitCode rejects (e.g. spawn errors).
160+ // Consumers frequently ignore duration; rejecting would surface as an unhandled rejection.
161+ const duration = exitCode . then (
162+ ( ) => performance . now ( ) - startTime ,
163+ ( ) => performance . now ( ) - startTime
164+ ) ;
149165
150166 // Register process group cleanup with DisposableProcess
151167 // This ensures ALL background children are killed when process exits
@@ -175,8 +191,13 @@ export abstract class LocalBaseRuntime implements Runtime {
175191 disposable [ Symbol . dispose ] ( ) ; // Kill process and run cleanup
176192 } , options . timeout * 1000 ) ;
177193
178- // Clear timeout if process exits naturally
179- void exitCode . finally ( ( ) => clearTimeout ( timeoutHandle ) ) ;
194+ // Clear timeout if process exits naturally.
195+ // Swallow rejections to avoid unhandled promise noise on spawn errors.
196+ exitCode
197+ . finally ( ( ) => clearTimeout ( timeoutHandle ) )
198+ . catch ( ( ) => {
199+ /* ignore */
200+ } ) ;
180201 }
181202
182203 return { stdout, stderr, stdin, exitCode, duration } ;
0 commit comments