Skip to main content
← Back to list
01Issue
BugOpenSwamp CLIPublicTeam
AssigneesNone

Relationships

#4282 serve reload never re-reads extension manifests; new additionalFiles reach workers only after a serve restart

Opened by nckrtl · 11/2/2026

Summary

swamp serve reload (and the serve.reload WebSocket request, which logs "Extension reload requested") re-registers local behaviors but never re-reads their extension manifests. resolveExtensionAssets caches each manifest's additionalFiles in a module-level extensionAssetsCache (a Map keyed by the manifest directory) that nothing clears. A file newly added to additionalFiles in an existing manifest is therefore not shipped to remote workers until serve restarts, and the behavior's ctx.extensionFile(...) read fails on the worker.

Version

swamp 20261031.063736.0-sha.e459d219, swamp serve --remote-only --hot-reload, local extensions in the repository's extensions/ directory, remote workers.

What we saw

  • We added scripts/swamp_workers.py to an existing manifest's additionalFiles, then ran swamp serve reload --server ... (it succeeded). A remote step that reads that file failed with No such file or directory: '<worker cache>/bundles/<fingerprint>/files/scripts/swamp_workers.py'.
  • Another behavior's manifest gained a script the same way; its first remote step failed with "This behavior has no co-located extension files to resolve". On the worker, WorkerBundleCache.#prefetchAssets received an empty asset list for that fingerprint.
  • Both worked after a serve restart, with no other change.

Code path

resolveExtensionAssets(sourcePath, repoDir) walks up to the nearest manifest.yaml, reads additionalFiles, and stores { filesRoot, additionalFiles } in extensionAssetsCache. runServeReload → modelRegistry.refreshSources(...) re-registers the type and calls resolveExtensionAssets again, which returns the cached entry. The cache has no reset hook.

Expected

An extension reload re-reads manifests (or clears extensionAssetsCache), so a release that adds a shipped script needs no serve restart. Restarting serve interrupts every in-flight run and scheduled fire, so for us each new script now waits for a quiet window.

Reproduce

  1. Local extension with a manifest and a behavior that calls ctx.extensionFile("scripts/a.py"); additionalFiles: [scripts/a.py]. Run it on a remote worker: works.
  2. Add scripts/b.py to additionalFiles, change the behavior to read it, run swamp serve reload --server <url>.
  3. Run the step on a remote worker: the file is missing from the worker's bundle files until serve restarts.
02Bog Flow
◉OPEN○TRIAGED○IN PROGRESS○SHIPPED

Open

11/2/2026, 6:17:12 AM

No activity in this phase yet.

03Sludge Pulse

Sign in to post a ripple.