Config: an unparseable config.yaml warns and exits 0, so a malformed config passes CI
Verified on @fission-ai/[email protected] (macOS, Node; exit codes captured directly, not through a pipe).
Summary
A config.yaml that is unparseable as a whole (e.g. an unterminated quote in a rules: item) makes the CLI warn
and carry on: openspec new change and openspec instructions print could not parse ... ignoring it. and exit 0.
openspec validate --all emits no warning about the config and also exits 0. So a malformed config is
indistinguishable from a healthy one to any gate keyed on exit status, and every rule in it is dropped with only a stderr
warning. (The one exception is a directory with no planning shape — no changes/ or specs/ directory — where a parser
failure does hard-error; see Reproduction.)
This is adjacent to, but distinct from, #1891. That issue covers a config that parses but whose rules: list stops
being an array of strings (an unquoted : turning an item into a mapping) — the CLI then emits a per-artifact
warning (Rules for '<artifact>' must be an array of strings, ignoring this artifact's rules). Here the whole file
fails to parse and the warning has a different shape (could not parse <path> (...); ignoring it.), so a gate that
matches the per-artifact wording (the natural guard for #1891) does not catch this class at all.
Reproduction
Put an unterminated quote in any rules: item (openspec/config.yaml, 3 lines):
rules:
proposal:
- 'Keep the "Why" section concrete: what breaks today
In an openspec/ tree that already has a planning shape (an openspec/changes/ or openspec/specs/ directory — in a config-only directory the CLI instead hard-errors with Invalid store declaration ... could not be read as YAML, exit 1):
$ openspec new change probe
- Creating change 'probe' with schema 'spec-driven'...
Warning: could not parse /path/to/openspec/config.yaml (Missing closing 'quote at line 4, column 1:); ignoring it.
Created change 'probe' at openspec/changes/probe/
$ echo $?
0
openspec instructions proposal --change probe --json warns on stderr, exits 0, and its JSON has no rules key (a
valid config yields a non-empty rules array).
openspec validate --all never reads the config's rules:; on an otherwise-valid tree it emits no warning about the
config and exits 0:
$ openspec validate --all
- Validating...
Totals: 1 passed, 0 failed (1 items)
$ echo $?
0
(Run it on a tree with no other problem: a delta-less change makes validate --all report Totals: 0 passed, 1 failed and exit 1 — so remove probe first, or the non-zero exit is about the change, not the config.)
So CI cannot tell a malformed config from a valid one, and (as in #1891) no project rule is applied.
What would help
- Fail (non-zero) on a config that cannot be parsed, or at minimum make
openspec validateerror on it, so a gate keyed on exit status catches it. A config the CLI cannot read is a hard error, not a warning — silently proceeding with zero project rules is the failure mode both issues share. - Cover the whole-file parse failure in the same fix as #1891 (or its own), since the two are the same class of bug — "configuration the CLI ignores without failing the build" — with different warning shapes. A project guarding one shape will miss the other.
- If failing is considered too breaking, emit both warnings from
validatetoo, so a single documented pattern (or a documented pair) is what projects must grep.
Source: Fission-AI/OpenSpec