-
-
Notifications
You must be signed in to change notification settings - Fork 41.2k
Closed
Labels
bugSomething isn't workingSomething isn't working
Description
Gateway crashes on config reload due to unhandled AbortError
Description
When configuration is patched via config.patch and the gateway restarts (SIGUSR1), the process frequently crashes with exit code 1 due to an unhandled AbortError.
Environment
- Clawdbot version: 2026.1.24-0
- OS: macOS (Apple Silicon)
- Node: v22.17.1
Steps to Reproduce
- Start the gateway normally
- Use
gateway config.patchto update configuration (e.g., add an API key) - Gateway receives SIGUSR1 and begins restart
- Process crashes with exit code 1
Error Log
22:55:13 [reload] config change detected; evaluating reload
22:55:13 [reload] config change requires gateway restart
22:55:13 [gateway] signal SIGUSR1 received
22:55:13 [gateway] received SIGUSR1; restarting
22:55:13 [gmail-watcher] gmail watcher stopped
22:55:13 [clawdbot] Unhandled promise rejection: AbortError: This operation was aborted
at node:internal/deps/undici/undici:13510:13
at processTicksAndRejections (node:internal/process/task_queues:105:5)
ELIFECYCLE Command failed with exit code 1.
Root Cause Analysis
In src/infra/unhandled-rejections.ts:
process.on("unhandledRejection", (reason, _promise) => {
if (isUnhandledRejectionHandled(reason)) return;
console.error("[clawdbot] Unhandled promise rejection:", formatUncaughtError(reason));
process.exit(1); // <-- exits immediately
});During graceful shutdown:
server.close()aborts in-flight network requests- Aborted requests throw
AbortError - If not caught, these become
unhandledRejection - Process exits with code 1
Suggested Fix
Register a global handler to suppress AbortError during shutdown:
// In src/infra/unhandled-rejections.ts
export function installUnhandledRejectionHandler(): void {
// Suppress AbortError globally - these are typically intentional cancellations
registerUnhandledRejectionHandler((reason) => {
if (reason instanceof Error && reason.name === "AbortError") {
console.warn("[clawdbot] Suppressed AbortError:", reason.message);
return true; // handled, don't exit
}
return false;
});
process.on("unhandledRejection", (reason, _promise) => {
if (isUnhandledRejectionHandled(reason)) return;
console.error("[clawdbot] Unhandled promise rejection:", formatUncaughtError(reason));
process.exit(1);
});
}Alternatively, register a temporary handler in gateway-daemon.ts only during the shutdown window.
Workaround
Configure launchd to auto-restart on crash:
<key>KeepAlive</key>
<dict>
<key>SuccessfulExit</key>
<false/>
<key>Crashed</key>
<true/>
</dict>
<key>ThrottleInterval</key>
<integer>5</integer>Impact
- Gateway becomes unavailable until manually restarted
- Users who are away from their machine lose connectivity to messaging channels
- Frequent config changes (e.g., during setup) trigger repeated crashes
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
bugSomething isn't workingSomething isn't working