Baike.dev
All toolsAI codingTrendingOpen sourceNewsSubmit
Log in
Back to tool/Back to issues
#1891·OpenSpec

Config rules: an unquoted ": " in a rules item silently drops the artifact's entire rule set

Author: aanbrnCreated Sep 14, 2026Updated Sep 14, 2026

Summary

A single malformed item in an artifact's rules: list makes the CLI ignore that artifact's entire rule set. The item is Keep the "Why" section concrete: what breaks today without the change — valid-looking YAML, but the unquoted : means YAML parses it as a mapping, so the list stops being an array of strings. The whole artifact's rules are then dropped, and the only signal is a warning on stderr.

Two things make this hard to notice:

  1. openspec validate does not check the config, so a config whose rules are being ignored validates clean. (openspec new change and openspec instructions do warn — see the output below — but CI runs validate --all, which is silent.)
  2. The failure is all-or-nothing. The list is rejected on its shape, not per item, so a project loses every rule for that artifact — including unrelated, well-formed ones.

Reproduction

# openspec/config.yaml
rules:
  proposal:
    - Keep the "Why" section concrete: what breaks today without the change
    - List "What Changes" at the file level
    - Declare "New Capabilities" / "Modified Capabilities" using existing capability names
  specs:
    - Requirements are declarative SHALL statements, testable via WHEN/THEN scenarios
    - Delta specs use ADDED/MODIFIED/DEPRECATED/REMOVED requirement blocks
    - Keep scenario wording consistent with existing captured specs

rules.proposal[0] contains an unquoted : , so YAML yields a mapping where the array expects a string:

[{"Keep the \"Why\" section concrete": "what breaks today without the change"}, "List ...", "Declare ..."]
$ openspec new change probe
- Creating change 'probe' with schema 'spec-driven'...
Rules for 'proposal' must be an array of strings, ignoring this artifact's rules
Created change 'probe' at openspec/changes/probe/

$ openspec instructions proposal --change probe --json 2>/dev/null | jq 'has("rules")'
false                                  # key omitted entirely — all three rules gone, including the two well-formed ones

$ openspec instructions specs --change probe --json 2>/dev/null | jq '.rules | length'
3                                      # the well-formed artifact's rules load fine

$ openspec validate --all
# exits without a config-rules warning (the probe change itself is not valid yet:
# it has no delta, so no spec validation runs)

(The warning is on stderr, so capturing it alongside stdout needs 2>&1.)

Verified on 1.13.0 (installed) and 1.11.0 (npx @fission-ai/[email protected]) — identical warning text and behaviour on both.

What would help

Any of these, roughly in order of how much they'd have saved us:

  1. Report the offending item, not just the artifact — e.g. rules.proposal[0] is not a string (found a mapping; did you mean to quote the scalar?). We bisected the list by hand to find it.
  2. Fail or warn in validate. validate --all is what CI runs; a config the CLI cannot fully read arguably belongs in its scope, or at least should not validate silently clean.
  3. Consider not discarding the whole list — one unparseable item taking out its siblings' rules compounds the first problem.

Why it bit us

We declared rules for four artifacts in August. Two were being ignored from then until we found this ~5 weeks later, because the warning appears wherever the rules are read and we had been treating stderr on new change as noise; validate never showed it. The dropped set included Declare "New Capabilities" / "Modified Capabilities" using existing capability names — a rule we kept forgetting. We only found it by probing the CLI's read path directly (openspec instructions <artifact> --json | jq 'has("rules")'). Quoting the two offending scalars fixed it.

Source: Fission-AI/OpenSpec

View original on GitHubView discussion on GitHub