Skip to content

Commit fb41529

Browse files
committed
docs(claude): add terse vs verbose balance to ERROR MESSAGES
Splits the doctrine into three audience tiers so contributors do not bloat library-API errors when the same four ingredients apply at different verbosity levels: - Library-API errors (caller-facing): terse, four ingredients may collapse into one line. Messages get asserted on in consumer tests — short + stable matters. - Validator/config errors (build-time): verbose, each ingredient spelled out. The reader is in a file looking for the record. - Programmatic errors (internal assertions): terse, rule only. Adds a bloat test — if removing a word loses information keep it, if it only loses rhythm drop it. Counter-example shows a bloated library error that restates the rule three times versus the ingredient-complete terse version. Mirrored to socket-repo-template.
1 parent 63d23d6 commit fb41529

1 file changed

Lines changed: 21 additions & 6 deletions

File tree

CLAUDE.md

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -90,23 +90,38 @@ The umbrella rule: never run a git command that mutates state belonging to a pat
9090

9191
## ERROR MESSAGES
9292

93-
Errors are a UX surface. When validating config or enforcing invariants, every error message must let the reader fix the problem without reading the source. Four ingredients, in order:
93+
Errors are a UX surface. Every error message must let the reader fix the problem without reading the source. Four ingredients, in order:
9494

9595
1. **What**: the rule that was violated (the contract, not the symptom)
9696
2. **Where**: the exact file, key, line, or record — never "somewhere in config"
9797
3. **Saw vs. wanted**: the offending value and the allowed shape/set
9898
4. **Fix**: one concrete action to resolve it
9999

100-
- Write the fix step in the imperative (`add "filename" to part 3`), not passive narration (`"filename" was missing`)
101-
- Never say "invalid" without what made it invalid. `invalid filename 'My Part'` is a symptom; `filename 'My Part' must be [a-z]+ (lowercase, no spaces)` is a rule
102-
- If two records collide, name both — not just the second one found
103-
- Suggest, don't auto-correct. An error that silently repairs state hides the bug in the next run
100+
Find the balance between terse and meaningful — meaningful does not mean bloated:
104101

105-
Example — validator on `tour.json`:
102+
- **Library-API errors** (thrown from the published package to its callers): terse. A caller catching and asserting on the message needs it short and stable. The four ingredients may collapse into one line; `name "__proto__" cannot start with an underscore` carries all four (what = start-rule, where = name component, saw = `__proto__`, fix implied by the rule).
103+
- **Validator / config errors** (build-time, developer-facing): verbose. The reader is staring at a file, needs to find the offending record, and won't re-run the tool to spot the next hit. Every ingredient gets its own words.
104+
- **Programmatic errors** (internal assertions, invariant checks): terse, rule-only. No caller will parse the message; terse keeps the check readable.
105+
106+
Baseline rules that apply to all three:
107+
108+
- Write the fix step in the imperative (`add "filename" to part 3`), not passive narration (`"filename" was missing`).
109+
- Never say "invalid" without what made it invalid. `invalid filename 'My Part'` is a symptom; `filename 'My Part' must be [a-z]+ (lowercase, no spaces)` is a rule.
110+
- If two records collide, name both — not just the second one found.
111+
- Suggest, don't auto-correct. An error that silently repairs state hides the bug in the next run.
112+
- Bloat test: if removing a word loses information, keep it. If removing it loses only rhythm, drop it.
113+
114+
Example — validator on `tour.json` (verbose form, one record per run):
106115

107116
-`Error: invalid tour config`
108117
-`tour.json: part 3 ("Parsing & Normalization") is missing "filename". Add a single-word lowercase filename (e.g. "parsing") to this part — one per part is required to route /<slug>/part/3 at publish time.`
109118

119+
Example — library API error (terse form, caught in user code):
120+
121+
-`Error: invalid component` (misses what / saw)
122+
-`The "name" component of type "npm" failed validation because the provided value "" is empty, which is not allowed because names are required; please provide a non-empty name.` (bloated — restates the rule three times)
123+
-`npm "name" component is a required component` (rule + where + implicit saw=missing)
124+
110125
## ABSOLUTE RULES
111126

112127
- Never create files unless necessary; always prefer editing existing files

0 commit comments

Comments
 (0)