Relationships
#1001 swamp serve should survive bad extension failures
Opened by evrardjp · 7/6/2026· Shipped 7/7/2026
Summary
swamp serve should be resilient to bad extension behavior. A model/workflow failure caused by an extension should be reported as a failed run, not bring down the whole server process.
Example observed
A third-party extension, @adam/cfgmgmt, appears to create a detached rejecting promise in its SSH helper:
const promise = _establishConnection(opts, key, port);
inflight().set(key, promise);
promise.finally(() => inflight().delete(key));
return promise;When SSH connection establishment failed for an unreachable VM, Deno surfaced this as an uncaught promise rejection and swamp serve crashed:
error: Uncaught (in promise) Error: SSH ControlMaster failed for 192.168.164.10:22:admin after 10 attempts: ssh: connect to host 192.168.164.10 port 22: No route to host
throw new Error(`SSH ControlMaster failed for ${key} after ${maxRetries + 1} attempts: ${stderr}`);
^
at _establishConnection (.../.swamp/bundles/ae74233e/adam/cfgmgmt/systemd.js?fp=839f7f2bf0ada6fdb517eff39ee80e2eb8eb07834bfd9e67a9d553ed76f32eff:110:13)The extension bug is tracked separately in #999. This issue is about the swamp serve host boundary.
Expected behavior
Even if an extension has a bug such as an unhandled rejection, swamp serve should ideally:
- keep serving other requests;
- mark the relevant method/workflow run as failed;
- record the extension error in the run output/logs;
- avoid leaving stale active runs behind.
Actual behavior
The server process crashed with Uncaught (in promise), and stale active runs had to be reaped manually with:
swamp run doctor --fix --jsonPossible approaches
- Execute extension/model method code in an isolation boundary so uncaught errors/rejections cannot terminate the
swamp servesupervisor. - Add top-level
unhandledrejection/uncaughtExceptionhandling for server-hosted method execution and convert failures into failed run records where safe. - Ensure run tracking cleanup happens in a
finally/supervisor path even if extension code escapes with an unhandled rejection.
I realize not every bad extension behavior can be safely recovered from in-process, but a single extension/model failure should not normally take down the whole long-running server.
Shipped
Click a lifecycle step above to view its details.