Description
A Pydantic schema exists in app/schema.py but is only used for documentation generation. The runtime Config.validate() (app/config.py) is hand-rolled and never rejects unknown keys at the top level, library level, or inside exclude blocks (the Seerr/Radarr/Sonarr sub-validators do reject unknowns; everywhere else is unchecked).
The result: a typo silently disables the setting the user thinks is active.
Failure Scenario
excludes: instead of exclude: => the entire exclusion block is ignored, everything is deletable
last_watch_threshold instead of last_watched_threshold => threshold never applies
genre: instead of genres: => genre protection off
The user sees a valid startup, a normal run, and deleted media they thought was protected. For a deletion tool, config typos should be startup errors, not silent no-ops.
Proposed Fix
- Enforce the existing Pydantic schema at load time with
extra="forbid", or add recursive unknown-key rejection to the hand-rolled validator
- Error message should name the unknown key and its location, and suggest the nearest valid key
- Fail at startup (before any processing), consistent with the existing fail-fast config errors
Description
A Pydantic schema exists in
app/schema.pybut is only used for documentation generation. The runtimeConfig.validate()(app/config.py) is hand-rolled and never rejects unknown keys at the top level, library level, or insideexcludeblocks (the Seerr/Radarr/Sonarr sub-validators do reject unknowns; everywhere else is unchecked).The result: a typo silently disables the setting the user thinks is active.
Failure Scenario
excludes:instead ofexclude:=> the entire exclusion block is ignored, everything is deletablelast_watch_thresholdinstead oflast_watched_threshold=> threshold never appliesgenre:instead ofgenres:=> genre protection offThe user sees a valid startup, a normal run, and deleted media they thought was protected. For a deletion tool, config typos should be startup errors, not silent no-ops.
Proposed Fix
extra="forbid", or add recursive unknown-key rejection to the hand-rolled validator