A misspelled config key is dropped by serde and nothing says so, so the option silently does not apply. check is the command whose whole job is to tell you what a release will do, and it reports nothing.
Reproduced
{
"workspace": { "hooks": { "post-bump": "echo nope", "postBumpp": "echo nope2" } },
"package": [{ "name": "core", "path": ".", "versionedFiles": [] }]
}
$ ferrflow check
FerrFlow — Check (dry run)
● core 0.0.0 → 0.1.0 (minor, bootstrapped)
$ echo $?
0
Both hooks are gone. No warning, no hint, exit 0. The first spelling is the plausible one: kebab-case is what most release tools use for hook names, and HooksConfig accepts only pre_bump / preBump and friends.
This is not specific to hooks. No config type carries deny_unknown_fields, so it applies to every key in ferrflow.json, ferrflow.js and the rest: a typo anywhere reads as "the default was fine".
The failure mode is the expensive kind. A hook that never fires looks exactly like a hook that fired and did nothing, and the config is right there in front of you looking correct. #998 was the same shape narrowed to three publisher fields, fixed by adding the missing aliases; this is the general case that made #998 possible.
Options
#[serde(deny_unknown_fields)] across the config types. Correct and free, but it is a hard error on configs that work today, so it is a breaking change and wants a major.
- Warn, do not fail. Deserialize into a
serde_json::Value alongside the typed config, walk both, and report keys the typed shape did not consume. Not breaking, catches typos, and fits check's existing job of reporting rather than enforcing. More code than option 1, and the walk has to understand the untagged enums (BuildMetadata, OnFailure) that legitimately accept several shapes.
- Warn now, deny at the next major. Option 2 shipped first so people can clean up, then option 1 when a major is cut anyway.
Option 3 unless there is a reason to hurry. A --strict-config flag opting into the hard error early would make the migration a choice rather than a surprise.
Suggested scope
- Report unknown keys with their path (
workspace.hooks.post-bump, not just post-bump).
- Suggest the nearest valid key when one is close, since the realistic cause is a typo or the wrong case convention.
- Emit from
check and from release, not only check, so CI catches it too.
Found while working on #802, where the same "unknown hook keys are dropped by serde" behaviour is what makes the hook-key injection in that issue unreachable. Worth having on record independently.
A misspelled config key is dropped by serde and nothing says so, so the option silently does not apply.
checkis the command whose whole job is to tell you what a release will do, and it reports nothing.Reproduced
{ "workspace": { "hooks": { "post-bump": "echo nope", "postBumpp": "echo nope2" } }, "package": [{ "name": "core", "path": ".", "versionedFiles": [] }] }Both hooks are gone. No warning, no hint, exit 0. The first spelling is the plausible one: kebab-case is what most release tools use for hook names, and
HooksConfigaccepts onlypre_bump/preBumpand friends.This is not specific to hooks. No config type carries
deny_unknown_fields, so it applies to every key inferrflow.json,ferrflow.jsand the rest: a typo anywhere reads as "the default was fine".The failure mode is the expensive kind. A hook that never fires looks exactly like a hook that fired and did nothing, and the config is right there in front of you looking correct. #998 was the same shape narrowed to three publisher fields, fixed by adding the missing aliases; this is the general case that made #998 possible.
Options
#[serde(deny_unknown_fields)]across the config types. Correct and free, but it is a hard error on configs that work today, so it is a breaking change and wants a major.serde_json::Valuealongside the typed config, walk both, and report keys the typed shape did not consume. Not breaking, catches typos, and fitscheck's existing job of reporting rather than enforcing. More code than option 1, and the walk has to understand the untagged enums (BuildMetadata,OnFailure) that legitimately accept several shapes.Option 3 unless there is a reason to hurry. A
--strict-configflag opting into the hard error early would make the migration a choice rather than a surprise.Suggested scope
workspace.hooks.post-bump, not justpost-bump).checkand fromrelease, not onlycheck, so CI catches it too.Found while working on #802, where the same "unknown hook keys are dropped by serde" behaviour is what makes the hook-key injection in that issue unreachable. Worth having on record independently.