Workflow-scope user extension reports don't execute: getAll() excludes lazy-loaded reports
Opened by stack72 · 4/10/2026
Description
User extension reports with scope: "workflow" don't execute during swamp workflow run even when listed in the workflow definition's reports.require field. The builtin @swamp/workflow-summary works because it's registered directly in builtin/mod.ts, not through the lazy loading path.
Steps to Reproduce
- Create a workflow-scope report in
extensions/reports/:
export const report = {
name: "@swamp/ci/eval-analysis",
scope: "workflow",
execute: async (context) => ({ markdown: "# Report", json: {} }),
};- Require it in a workflow definition:
reports:
require:
- "@swamp/ci/eval-analysis"- Run the workflow once (bootstraps catalog via full import).
- Run the workflow again (catalog populated, takes lazy path).
- The user report silently does not execute. Only
@swamp/workflow-summaryruns. swamp report describe "@swamp/ci/eval-analysis"works, confirming the report IS registered as lazy.
Environment
- macOS Darwin 25.3.0
- swamp CLI (latest)
- Local extensions in
extensions/reports/
Root Cause Analysis
In report_execution_service.ts, executeReports() calls registry.getAll() which only returns entries from the this.reports Map (fully-loaded). It does not include entries from this.lazyTypes.
When the extension catalog is already populated (second+ run), UserReportLoader.loadOrRegisterLazy() calls registerLazyFromCatalog() which registers reports as lazy entries only. These are never promoted to fully-loaded before executeReports() runs.
The ensureLoaded() call in workflow_run.ts:219 triggers loadOrRegisterLazy(), but if the catalog is populated and files are not stale, it takes the lazy path and returns without fully importing the bundles.
Suggested Fix
In executeReports(), before calling registry.getAll(), iterate selection.require names and call registry.ensureTypeLoaded(name) for each. This promotes lazy entries to fully-loaded before filtering.
Open
No activity in this phase yet.
Sign in to post a ripple.