Skip to content

fix(web): preserve dotted schema keys when saving plugin config#370

Merged
ChuckBuilds merged 1 commit into
ChuckBuilds:mainfrom
rpierce99:fix/web-config-dotted-league-keys
Jun 15, 2026
Merged

fix(web): preserve dotted schema keys when saving plugin config#370
ChuckBuilds merged 1 commit into
ChuckBuilds:mainfrom
rpierce99:fix/web-config-dotted-league-keys

Conversation

@rpierce99

Copy link
Copy Markdown
Contributor

Problem

The plugin config form posts form-data with dot-notation paths (e.g. leagues.fifa.world.enabled). The two helpers that resolve those paths — _get_schema_property and _set_nested_value in web_interface/blueprints/api_v3.py — split on every dot. When a schema key itself contains a dot (soccer league keys like fifa.world, eng.1, usa.1), the dotted key was mistaken for nested fifaworld objects:

  • _get_schema_property("leagues.fifa.world.favorite_teams") returned None, so the field wasn't recognized as an array and the value was dropped/mistyped.
  • _set_nested_value(cfg, "leagues.fifa.world.enabled", True) created a fabricated leagues["fifa"]["world"] branch and left the real leagues["fifa.world"] untouched.

Net effect: every per-league edit (enable, favorite teams, nested booleans) was silently discarded. The save wrote the unchanged config and the file came out byte-identical, so users saw no error but no change either. This affects every league, since they all use dotted keys.

The frontend already solved this for its JSON path (greedy longest-match in getSchemaProperty/dotToNested), but the server-rendered form posts form-data to this backend path, which was never fixed.

Fix

Both helpers now greedily match the longest path segment that exists in the schema (_get_schema_property) or in the config being updated (_set_nested_value), so leagues.fifa.world.* resolves to the real leagues["fifa.world"] object. This mirrors the existing frontend behavior. Plain nested paths (no dotted keys) are unaffected.

Tests

Adds test/web_interface/test_dotted_league_keys.py (6 cases): schema lookup for dotted keys and nested objects beneath them, value typing ("USA"["USA"]), writes landing in the real league (no fabricated branch), writes into a not-yet-present leaf, plus a guard that plain nested paths still work. Verified the dotted-key cases fail before this change and pass after; the plain-nesting guard passes both ways.

🤖 Generated with Claude Code

The plugin config form posts form-data with dot-notation paths
(e.g. "leagues.fifa.world.enabled"). _get_schema_property and
_set_nested_value split those paths on every dot, so a schema key that
itself contains a dot (soccer league keys like "fifa.world", "eng.1")
was mistaken for nested "fifa" -> "world" objects. Per-league edits
(enable, favorite_teams, nested booleans) were written to a fabricated
"leagues.fifa.world" branch while the real league object was never
updated, so saves silently dropped the change and produced a
byte-identical config.

Both helpers now greedily match the longest path segment that exists in
the schema (_get_schema_property) or the config being updated
(_set_nested_value), mirroring the frontend's dotted-key handling.

Adds regression tests covering schema lookup, value typing, and writes
under dotted league keys, plus a guard that plain nested paths still work.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jun 13, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@rpierce99, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 25 minutes and 4 seconds. Learn how PR review limits work.

Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file).

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 30e2d26c-d678-4123-8d6e-cad28bb21668

📥 Commits

Reviewing files that changed from the base of the PR and between d22d0a3 and c6b2bdf.

📒 Files selected for processing (2)
  • test/web_interface/test_dotted_league_keys.py
  • web_interface/blueprints/api_v3.py
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@codacy-production

Copy link
Copy Markdown

Up to standards ✅

🟢 Issues 0 issues

Results:
0 new issues

View in Codacy

NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.

@ChuckBuilds ChuckBuilds merged commit ab0cfd2 into ChuckBuilds:main Jun 15, 2026
3 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.

2 participants