Relationships
#2234 Hot-reload serve.yaml webhook routes (like trigger overrides), not just at startup
Opened by magistr · 9/17/2026· Shipped 9/18/2026
Problem statement
swamp serve --hot-reload + swamp serve reload (SIGHUP / --server reload)
re-reads much of the running config without a restart: performHotReload in
src/serve/extension_reload.ts reloads extension bundles/types (models, vaults,
datastores, reports, webhooks), refreshes trusted collectives, reloads
workflows, and — via triggerOverrideUpdater — re-reads config.triggers from
serve.yaml (it calls readServeConfigFile(repoDir) and rebuilds the trigger
override map).
It does NOT re-read config.webhooks. The webhook endpoint list from serve.yaml
is parsed and its routes registered only at startup (src/serve/serve_config.ts
parses webhooks; the routes are wired when serve boots). So adding a new
webhook route — or changing an existing route's workflow/secret/scheme/config —
requires a full container restart, even though the webhook type it references
(a webhook extension, #2204) and the target workflow both already hot-reload.
Concretely: deploying a new webhook-backed integration hot-reloads the
extension + the workflow, but the - route: /hooks/… binding that ties them
together is stranded until restart, which is the disruptive part on an always-on
serve (it re-bundles models and briefly drops the listener).
Verified on 20260917.032111.0-sha.614bbc7e.
Proposed solution
Re-read config.webhooks in the hot-reload path, mirroring the existing
triggerOverrideUpdater:
- Add a
webhookConfigUpdater(or fold into the existing config re-read) that, on reload, re-parsesconfig.webhooksviareadServeConfigFile(repoDir)and diffs it against the live route table: register added routes, drop removed ones, update changed workflow/secret/scheme/config bindings. - Resolve extension-scheme handlers through the (already reloadable) webhook
type registry, so a route + its
@collective/nameverifier can be added in one reload. - Re-validate entries the same way startup does; on a bad entry, keep the prior route table and surface the error in the reload result (as other reload sub-steps already do) rather than dropping routes.
Alternatives considered
- Restart on any webhook-route change — current behavior; defeats the point of hot-reload for exactly the integrations webhook extensions (#2204) just enabled.
- Express routes outside serve.yaml (e.g. a model/CLI to register routes at runtime) — larger surface; serve.yaml is already the single source of truth for webhooks and triggers, and triggers already hot-reload, so webhooks should match.
Shipped
Click a lifecycle step above to view its details.
stack72 commented 9/18/2026, 3:59:42 PM
Thanks @magistr for reporting this! We shipped: Extend the hot-reload path (performServeReload) to also re-read config.webhooks from serve.yaml, mirroring the existing triggerOverrideUpdater pattern. Add an updateEndpoints() method to WebhookService for atomic route table swaps, wire a webhookUpdater callback through ServeReloadOptions, and surface the result via a new webhooksReloaded field on ServeReloadResponse. On error, keep the prior route table. Only reload when the webhook source was serve.yaml (not CLI --webhook flags).. The fix has been merged and a release is on its way. We appreciate your contribution to swamp.
Sign in to post a ripple.