moeru-ai/airi · error · Error
Previous Godot stage process is still shutting down. Retry a
Error message
Previous Godot stage process is still shutting down. Retry after it exits.
What it means
Thrown by the start handler inside the lifecycle mutex after it detected an existing currentProcess in a non-'starting' state, called stopProcessAfterFailedStart to tear it down, and then observed currentProcess === activeProcess — meaning the old process handle did not clear during shutdown. The start refuses to proceed to avoid double-process state.
Source
Thrown at apps/stage-tamagotchi/src/main/services/airi/godot-stage/index.ts:718
return await lifecycleMutex.runExclusive(async () => {
let spawnedProcess: GodotStageProcess | undefined
try {
if (currentProcess && currentStatus.state === 'running') {
return currentStatus
}
if (currentProcess && currentStatus.state === 'starting' && currentReady) {
await currentReady.promise
return currentStatus
}
if (currentProcess) {
const activeProcess = currentProcess
await stopProcessAfterFailedStart()
if (currentProcess === activeProcess) {
throw new Error('Previous Godot stage process is still shutting down. Retry after it exits.')
}
}
await stopSocketRuntime()
const socketRuntime = await startSocketRuntime()
const godotBinary = await resolveGodotBinary()
const websocketUrl = `ws://127.0.0.1:${socketRuntime.port}/ws?token=${socketRuntime.token}`
const readyDeferred = createDeferred<void>()
const readyTimeout = setTimeout(() => {
readyDeferred.reject(new Error('Godot stage did not report ready in time.'))
}, 20_000)
currentReady = readyDeferred
expectedProcessExit = false
setStatus({
state: 'starting',
pid: null,View on GitHub (pinned to 27111382b4)
Solutions
- Retry electronGodotStageStart after the previous process actually exits (its pid disappears from the process table).
- If the Godot child is wedged, kill it externally, then restart.
- Ensure stopProcessAfterFailedStart fully awaits process exit and clears currentProcess; if it does not, report it as a lifecycle bug.
- Avoid hammering start while a shutdown is in flight; debounce or disable the control until status returns to stopped.
Defensive patterns
Strategy: retry
Try / catch
try {
await electronGodotStageStart()
}
catch (error) {
if (errorMessageFrom(error)?.startsWith('Previous Godot stage process is still shutting down')) {
// wait until status returns 'stopped' and the old pid is gone, then retry
}
} Prevention
- Wait for the previous process to fully exit before restarting.
- Kill a wedged Godot child externally if it ignores shutdown.
- Debounce the start control to avoid hammering during shutdown.
When it happens
Trigger: Calling electronGodotStageStart while a previous Godot process handle is still assigned to currentProcess (e.g. a failed prior start whose exit handler hasn't fired), and stopProcessAfterFailedStart did not null out currentProcess before the equality check.
Common situations: Repeated start attempts after a failed launch; the Godot child process ignoring SIGTERM and lingering; exit handler that clears currentProcess racing with the restart; rapid start/stop toggling in the UI.
Related errors
- Godot stage is not running.
- Godot stage bridge is not connected.
- Invalid Godot stage scene input payload.
- Unable to locate engines/stage-tamagotchi-godot/project.godo
- Godot stage exported binary not found. Expected at: ${join(p
AI-assisted analysis of moeru-ai/airi@27111382b4 (2026-08-12).
Data as JSON: /api/errors/f2f23e15971fb8ef.
Report an issue: GitHub.