Skip to content

Reject unknown config keys; stop mutating the input config during resolution#39

Merged
Str4vinci merged 2 commits into
developfrom
feature/config-validation
Jun 26, 2026
Merged

Reject unknown config keys; stop mutating the input config during resolution#39
Str4vinci merged 2 commits into
developfrom
feature/config-validation

Conversation

@Str4vinci

@Str4vinci Str4vinci commented Jun 24, 2026

Copy link
Copy Markdown
Owner

Summary

Two related config-layer hardening items from the 0.3.2 roadmap.

Reject unknown config keys

validate_config now rejects unknown top-level keys. Previously a typo such as batery_kwh slipped through merge_defaults ({**DEFAULTS, **config}) and silently defaulted — e.g. the battery to 0 — so the run succeeded and returned plausible-but-wrong numbers with no warning. A real footgun for parametric/batch studies driven by many config files.

It now raises listing the offending key(s), in the existing "Unknown X. Available: ..." style. The allowed set is derived from DEFAULTS plus the required inputs (location, annual_consumption_kwh, n_modules) and the optional montecarlo section (consumed by the Monte Carlo runner/CLI, which validates the same dict), so it stays in sync automatically as config keys are added.

Stop mutating the input config during resolution

resolve_pv_system previously did cfg["n_modules"] = sum(...), writing into the same dict the frozen=True ResolvedAppConfig wraps — making the immutability partly cosmetic and the data flow harder to follow. It now returns the resolved module count, and resolve_app_config materialises it into a fresh dict, so the wrapped config is built once and the caller's input dict is left untouched.

Tests

7 new tests: unknown-key rejection (including that the offending key is named), the montecarlo section staying allowed, and that resolving pv_arrays no longer mutates the caller's dict while still deriving n_modules correctly. Full suite green, ruff clean.

Docs

Config reference note on strict key validation + CHANGELOG [Unreleased].

Note on overlap with #38

Both PRs touch app_config.py in non-overlapping regions and merge cleanly in either order. Because the allowed-key set is derived from DEFAULTS, the new keys added in #38 are automatically accepted once both land.

Add an allowed-key check to validate_config so a misspelled top-level key
(e.g. batery_kwh) raises listing the offending key instead of being silently
dropped by merge_defaults and defaulting — a footgun for batch/parametric
studies that returned plausible-but-wrong numbers. The allowed set is derived
from DEFAULTS plus the required inputs and the optional montecarlo section, so
it stays in sync as config keys are added.

Also stop resolve_pv_system from writing the derived n_modules back into the
merged config in place. It now returns the resolved count and resolve_app_config
materialises it into a fresh dict, so the dict wrapped by the frozen
ResolvedAppConfig is built once and the caller's input dict is left untouched.

Targets the 0.3.1 roadmap config-validation items.
@Str4vinci Str4vinci merged commit 4cbb42a into develop Jun 26, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant