Displays: clicking a DVI monitor crashes the section with each_key_duplicate #63

Closed
opened 2026-10-13 19:09:02 +08:00 by Breadway · 2 comments
Owner

How it was found: user report on 2026-10-13 with a screenshot. Clicking a monitor in Displays replaced the page with "This section couldn't load. https://svelte.dev/e/each_key_duplicate".

Confidence: high. Confirmed against the user's live hyprctl monitors all -j capture (/tmp/opencode/bset49/monitors-all.json). DVI-I-1 and DVI-I-2 each report 30 availableModes but only 25 unique: 1920x1080@60.00Hz, 1280x720@60.00Hz, 640x480@59.94Hz, 720x480@59.94Hz and 720x480@60.00Hz appear twice. eDP-1 has no duplicates and loads fine.

Bug: frontend/src/lib/views/Display.svelte line 330 renders the resolution picker with {#each live.available_modes as mode, i (mode)}, keyed by the mode string. Svelte 5 throws each_key_duplicate on a repeated key, and the section error boundary takes out the whole Displays section.

Fix: remove duplicate modes in the backend where available_modes is parsed (keeping the original order), and stop keying the picker by a value that is not guaranteed unique. Add a test using the fixture.

**How it was found:** user report on 2026-10-13 with a screenshot. Clicking a monitor in Displays replaced the page with "This section couldn't load. https://svelte.dev/e/each_key_duplicate". **Confidence:** high. Confirmed against the user's live `hyprctl monitors all -j` capture (/tmp/opencode/bset49/monitors-all.json). DVI-I-1 and DVI-I-2 each report 30 availableModes but only 25 unique: 1920x1080@60.00Hz, 1280x720@60.00Hz, 640x480@59.94Hz, 720x480@59.94Hz and 720x480@60.00Hz appear twice. eDP-1 has no duplicates and loads fine. **Bug:** frontend/src/lib/views/Display.svelte line 330 renders the resolution picker with `{#each live.available_modes as mode, i (mode)}`, keyed by the mode string. Svelte 5 throws each_key_duplicate on a repeated key, and the section error boundary takes out the whole Displays section. **Fix:** remove duplicate modes in the backend where available_modes is parsed (keeping the original order), and stop keying the picker by a value that is not guaranteed unique. Add a test using the fixture.
Author
Owner

Review of PR #67 (#67), exact head 7a55f598d6, base 14d13158 (unchanged). Verdict: PASS, not merged (reviewer has no Forgejo write or merge tools; awaiting merge by the coordinator).

Checks I ran independently in a detached scratch worktree at that SHA: frontend npm ci, npm run check (0 errors, 0 warnings), npm test, npm run build all pass. src: cargo fmt --check clean, cargo clippy --locked --all-targets -D warnings clean, cargo test --locked 168 passed. Forgejo CI "check / check (push)" is success on the exact head (run 141). PR is mergeable, no reviews or change requests exist.

BSET-62: hyprland.rs dedupe_keep_order in parse_monitors plus uniqueBy in Display.svelte; test duplicate_modes_are_removed_keeping_order asserts 25 unique for both DVI outputs from the fixture. Every keyed each in Display.svelte and Breadpaper.svelte is over static lists or names that are now unique. Pass.
BSET-49: resolve_mirror maps the numeric mirrorOf id to a name (fixture: DVI-I-1 mirrors eDP-1); groupMonitors draws the group; withMirror and the guard tests show unrelated changes keep the mirror and restore replays it. Pass.
BSET-48: display_guard.rs snapshots, validates, applies, reads back, reverts on failure, timeout, unplug, explicit Revert and exit; only keep persists. Validation refuses no-enabled-display, self-mirror and missing, off or mirroring sources. Frontend routes resolution, scale, rotation, vrr, drag and mirror through apply_display_layout. 28a6bfa revert_on_signal (SIGTERM/SIGINT/SIGHUP) is wired in lib.rs setup and is idempotent with the RunEvent::Exit hook. Pass, backed by mock-compositor tests plus the coordinator's live VM evidence (not reproduced by me).

Residual, out of scope: SIGKILL/crash (BSET-67), login include order (BSET-68).

Review of PR #67 (https://git.breadway.dev/Breadway/bos-settings/pulls/67), exact head 7a55f598d6c99792fc3d80521f77866e5e0490d6, base 14d13158 (unchanged). Verdict: PASS, not merged (reviewer has no Forgejo write or merge tools; awaiting merge by the coordinator). Checks I ran independently in a detached scratch worktree at that SHA: frontend npm ci, npm run check (0 errors, 0 warnings), npm test, npm run build all pass. src: cargo fmt --check clean, cargo clippy --locked --all-targets -D warnings clean, cargo test --locked 168 passed. Forgejo CI "check / check (push)" is success on the exact head (run 141). PR is mergeable, no reviews or change requests exist. BSET-62: hyprland.rs dedupe_keep_order in parse_monitors plus uniqueBy in Display.svelte; test duplicate_modes_are_removed_keeping_order asserts 25 unique for both DVI outputs from the fixture. Every keyed each in Display.svelte and Breadpaper.svelte is over static lists or names that are now unique. Pass. BSET-49: resolve_mirror maps the numeric mirrorOf id to a name (fixture: DVI-I-1 mirrors eDP-1); groupMonitors draws the group; withMirror and the guard tests show unrelated changes keep the mirror and restore replays it. Pass. BSET-48: display_guard.rs snapshots, validates, applies, reads back, reverts on failure, timeout, unplug, explicit Revert and exit; only keep persists. Validation refuses no-enabled-display, self-mirror and missing, off or mirroring sources. Frontend routes resolution, scale, rotation, vrr, drag and mirror through apply_display_layout. 28a6bfa revert_on_signal (SIGTERM/SIGINT/SIGHUP) is wired in lib.rs setup and is idempotent with the RunEvent::Exit hook. Pass, backed by mock-compositor tests plus the coordinator's live VM evidence (not reproduced by me). Residual, out of scope: SIGKILL/crash (BSET-67), login include order (BSET-68).
Author
Owner

Verified on integrated main a7b3e8b (merge 3407152, PR #67): fixture test asserts 25 unique modes for both DVI outputs (from 30 reported); uniqueBy guards keyed each blocks; cargo test 179 / npm test pass.

Verified on integrated main a7b3e8b (merge 3407152, PR #67): fixture test asserts 25 unique modes for both DVI outputs (from 30 reported); uniqueBy guards keyed each blocks; cargo test 179 / npm test pass.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
Breadway/bos-settings#63
No description provided.