google/zx · error · Fail
Too late to abort the process.
Error message
Too late to abort the process.
What it means
Thrown by ProcessPromise.abort() when the process has already settled (fulfilled or rejected). Once a process exits, there is no live child to abort, so zx refuses rather than silently no-op. The guard checks isSettled() (output already assigned).
Source
Thrown at src/core.ts:437
if (this.isSettled()) return
this._output = output
ProcessPromise.bus.unpipeBack(this)
if (output.ok || this.isNothrow()) {
this._stage = 'fulfilled'
this._resolve(output)
} else {
this._stage = 'rejected'
if (legacy) {
this._resolve(output) // to avoid unhandledRejection alerts
throw output.cause || output
}
this._reject(output)
if (this.sync) throw output
}
}
abort(reason?: string) {
if (this.isSettled()) throw new Fail('Too late to abort the process.')
if (this.signal !== this.ac.signal)
throw new Fail('The signal is controlled by another process.')
if (!this.child)
throw new Fail('Trying to abort a process without creating one.')
this.ac.abort(reason)
}
kill(signal?: NodeJS.Signals | null): Promise<void> {
if (this.isSettled()) throw new Fail('Too late to kill the process.')
if (!this.child)
throw new Fail('Trying to kill a process without creating one.')
if (!this.pid) throw new Fail('The process pid is undefined.')
return $.kill(this.pid, signal || this._snapshot.killSignal || $.killSignal)
}
// ConfiguratorsView on GitHub (pinned to 00a2c484e2)
Solutions
- Guard the call: `if (!pp.isSettled()) pp.abort()`.
- Move abort into the running window (before the awaited expression).
- Use $.timeout / pp.timeout() for time-bounded kills instead of manual abort.
Example fix
// before await pp pp.abort() // after if (!pp.isSettled()) pp.abort()
Defensive patterns
Strategy: validation
Validate before calling
// pp.isSettled() is private; track settlement externally
let settled = false
pp.then(() => { settled = true }).catch(() => { settled = true })
function safeAbort(p: ProcessPromise): void {
if (!settled) p.abort()
} Try / catch
try {
pp.abort()
} catch (e) {
if (e instanceof Fail && /Too late to abort/.test(e.message)) {
// already finished — nothing to do
} else throw e
} Prevention
- Guard every abort() with an isSettled() / stage check (or track settlement yourself).
- Prefer $.timeout for bounded execution over manual abort watchdogs.
- Wire abort to the 'start' event rather than to completion handlers.
When it happens
Trigger: Calling `pp.abort()` inside `.then()`, `.catch()`, or `.finally()`; after `await pp`; in a setTimeout/setInterval callback that fires after the process completed; abort logic racing with a fast command.
Common situations: Timeout/abort watchdogs that lose the race against quick commands; cleanup handlers running in finally blocks; abort wired to an event that fires post-completion.
Related errors
- The signal is controlled by another process.
- Trying to abort a process without creating one.
- sync mode does not allow async command resolution
- Too late to kill the process.
- Trying to kill a process without creating one.
AI-assisted analysis of google/zx@00a2c484e2 (2026-08-13).
Data as JSON: /api/errors/edf658dc9ce3eb62.
Report an issue: GitHub.