Stop on a malformed config or bindings file - #63
Merged
Conversation
A broken file was indistinguishable from an absent one: a syntax error in config.yaml fell back to the defaults, a syntax error in bindings.yaml left every key undefined, and a mapping or a scalar reached the menu untouched because nothing checked the shape of what was parsed. Deno.errors.NotFound is now the only silent fallback. Anything else raises a ConfigError and exits 7, reporting `<path>: <reason>` on stderr with $HOME abbreviated to `~`. The three files are read in a fixed order, so the first broken one wins and the rest are left untouched. BREAKING CHANGE: a malformed config.yaml used to exit 0 and let wk run on the defaults; it now exits 7 and refuses to start. Closes #59 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #59
Summary
A broken config file was indistinguishable from an absent one, so a typo silently changed how wk behaves.
Deno.errors.NotFoundis now the only silent fallback; anything else — a syntax error, a shape mismatch, EACCES, EISDIR — raises aConfigErrorand exits 7.Background
config.yamlbindings.yamlbindings.yamlholds a mapping or a scalar[].concat({foo:'bar'})yields a one-element list and the bogus entry reaches the menuconfig.yamlholds a scalar (42)mergeContext(42)passesTwo causes.
.catch(() => fallback)inrun.tscould not tell "the file is not there" from "the file is broken", and nothing validated the shape of what was parsed.Changes
src/errors.ts: addConfigError, carrying the path and the reason.src/run.ts:loadYaml: onlyNotFoundfalls back, everything else raisesConfigError.null, comments only,---,~) still falls back, keeping the behaviour (config, bindings): an empty config file crashes instead of falling back #58 landed.config.yaml, the globalbindings.yaml, then the localwk.bindings.yaml— so the first broken file is the one reported and the rest are left unread. The previousPromise.allconcurrency is dropped; it bought nothing, becausetui.init()'s cursor-position query is a synchronous blocking read that stalled those loads anyway.wk:prefix since the widget adds its own, and$HOMEabbreviated to~:<path>: <first line of the @std/yaml message>for a syntax error — it already carriesat line N, column M; the excerpt and caret that follow are dropped so the message fitszle -M.<path>: invalid formatfor a shape mismatch.src/widget.eta: comment only. Its*)arm already forwards an unknown exit code tozle -M, so no behavioural change.Scope of the validation
A small hand-written check, so no new dependency:
config.yamlmust be a non-null, non-array object.key.Field types (
type,buffer, …) and nestedbindings:are deliberately not checked.Breaking change
Yes. A malformed
config.yamlused to exit 0 and let wk keep running on the defaults; it now exits 7 and refuses to start. Input that used to succeed now fails, so this belongs in v2.0.0.This PR alone does not ship v2.0.0. The field-type validation left out above is to be added first, and v2.0.0 released after that.
Verification
mise run checkpasses.e2e/tests/04_config.batsis now 19 tests: the two that pinned the silent fallbacks are updated to exit 7, and eight cases are added —wk.bindings.yamlfails fast just like the global layer,key, a scalar),config.yaml,$HOMEis reported with a tilde.The new assertions match on the path prefix and
at line N, column Mrather than pinning@std/yaml's wording or the errno string verbatim, sincee2e/helpers/common.bashstates the suite may not reference Deno and doubles as an acceptance spec for any future reimplementation.