Skip to content

fix: surface malformed-bundle errors + unknown-field warnings (discovery loader output)#25

Merged
vessux merged 9 commits into
mainfrom
worktree-fix+6-discovery-loader-output
Jun 18, 2026
Merged

fix: surface malformed-bundle errors + unknown-field warnings (discovery loader output)#25
vessux merged 9 commits into
mainfrom
worktree-fix+6-discovery-loader-output

Conversation

@vessux

@vessux vessux commented Jun 18, 2026

Copy link
Copy Markdown
Owner

Summary

Bundle discovery was discarding the manifest loader's output, so two distinct problems shared one root cause:

  • A malformed bundle (hard validation failure or a frontmatter parser throw) was reported as bundle '<name>' not found (exit 3) — indistinguishable from a typo'd name. The real, actionable error was thrown away.
  • Unknown-frontmatter-field warnings were computed by the loader but never surfaced — a misspelled key (skils:) was silently ignored.

This threads the loader's full result through BundleEntry and surfaces it across every command:

  • Malformed bundle → the underlying validation message, exit 2 (UsageError); a genuinely-absent name still → not found, exit 3 (NotFoundError). The two stay distinguishable.
  • A frontmatter parser throw (e.g. a : colon-space in an unquoted description) now becomes an actionable UsageError with a description: >- block-scalar hint (reusing the 73fdda7 pattern), not a raw YAMLException.
  • Unknown-field warnings are aggregated across the whole extends chain and surfaced: stderr on build/run/apply (exit 0 preserved), and merged into show's ## warnings section (de-duplicated).
  • umbel list flags a malformed row as NAME ⚠ with the reason in the DESCRIPTION column; clean bundles are unchanged.

Closes #6 (folds in #7, which was closed as a duplicate).

How it was built

TDD, 8 tasks, fresh subagent per task with two-stage (spec + code-quality) review, plus a final whole-branch review. Commits are scoped one-per-seam (manifest → discover → compose → exec → list → show → run → integration + a small emitWarnings DRY refactor).

Test Plan

  • npm test — 368/368 pass (39 files), incl. new test/integration/cli.bundle-malformed.test.ts
  • npx tsc --noEmit — clean
  • biome check . — clean
  • Live CLI verified: build <malformed> → exit 2 + real reason; build <ghost> → exit 3 + "not found"; build <unknown-field> → exit 0 + stderr warning; list shows row; show lists manifest warnings.

Follow-ups captured (out of scope)

  • umbel-8k9 — whether an unknown frontmatter field should fail-fast (hard error) vs the current documented soft-warning (forward-compat trade-off; needs an ADR + spec decision).
  • umbel-3gb — a malformed parent reached via extends still reports "missing parent" (exit 3) rather than the parent's real error (same class as this issue, one level removed).

@vessux vessux merged commit bd6e3e1 into main Jun 18, 2026
4 checks passed
@vessux vessux deleted the worktree-fix+6-discovery-loader-output branch June 18, 2026 09:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Discovery discards manifest-loader output: malformed bundles report 'not found' + unknown-field warnings swallowed

1 participant