Repository navigation
Description
Implementation: FlyBot (ours) — PR follows within 24h. Do not pick up without a pickup-ok comment on this issue.
Written-by: FlyBot Lead
Claimed-by: FlyBot Lead
Claim-Id: c228bfb6db5c4c038e8acf1b34e56873
Branch: dev/1-settings-refusal-line
Base: 9ede925
At: 2026-11-02T16:00:30Z
Owner: Dev-1
Tier: T1
What happens
Every write the host refuses while the Settings dialog is open is reported on the first line of the scrolling page, above the viewport once you have scrolled down — so the sentence that explains the refusal is painted outside the visible area and the control you just toggled stays as it was. In a read-only window the write is refused by design (core/src/host/channel.js:294-296, set-flags is not in READS), so this is the normal path there, not an edge case.
Evidence on live main 9ede9258 (identical in f88d9133):
core/src/client/settings.js:206builds the message:errorLine = h('div', { className: 'bt-error', role: 'alert', style: { padding: 0 } }, error).core/src/client/settings.js:226-227errorLineis the first child ofdiv.bt-settings-scroll, i.e. inside the element that scrolls.core/src/client/styles.js:497.bt-settings-scroll { flex: 1; overflow-y: auto; ... };core/src/client/styles.js:337.bt-error { ... }has noposition: sticky/fixed.core/src/client/settings.js:177-179the failure path only callssetError;grep -n "scrollTop\|scrollTo(" core/src/client/settings.js core/src/client/bot-settings.js→ 0 hits, nothing scrolls the message back into view.- The page is long enough for this to happen:
BotSettingsForm(core/src/client/bot-settings.js:196-269) draws 13 cards, andPin/Hide from sidebar(:257-258) and theMain Botswitch (:254) are all below the first screen.
Reproduction
- Open the same
~/.dshin a second dsh window (the second one is read-only — this is the normal waybot/read-onlyappears). - In that window: Settings → Bots → pick a Bot → scroll down to the Sidebar cards.
- Toggle
Pin(orHide from sidebar). - The host refuses with
bot/read-only; the sentence is written into.bt-error, but that node is at the top of the scrolling page and the viewport is below it. The switch renders frombot.pinned, so it does not move either. - Result: the click looks like it did nothing, and the reason is off-screen.
Expected behaviour
A refusal stays in view at the moment it happens: the sentence either sits next to the control that was refused, or is pinned outside the scrolling area (below .bt-settings-head, which does not scroll). This is the same rule the Workflow plugin now follows for its dialogs (#2193): the host's sentence is shown where the action was taken, not somewhere the user cannot see.
The usage page keeps its current behaviour.
Scope
core/src/client/settings.js— move the refusal line out of.bt-settings-scroll(to just below.bt-settings-head, above the scrolling page), with the horizontal padding matched to the page's own inset.core/test/settings-error-placement.test.js(new) — a test that drives the realSettingsDialogand asserts therole="alert"node is not a descendant of.bt-settings-scroll, with the text equal to the host's sentence.- Regenerated
core/client.jsand thepatches/ds-bot/*mirrors (0008-client-bundle.patch,0014-flybot-branding.patch,files/test/settings-error-placement.test.js). docs/subsystems/core-client.md— one sentence on where a refusal is drawn.changelog.d/<this issue>-settings-refusal-line.fixed.md.
Out of scope: changing what the host refuses, the wording of any host message, the behaviour of the individual forms, and .bt-error's global styling.
Prior art / duplicates
Searched before opening (settings refusal, bt-settings-scroll, settings alert scroll, and the closed set around bt-error):
#2176/#2187are the two Workflow settings pages' read-only entry points — the plugin page, not this dialog.#2193(open, ours) is the same defect class in the Workflow plugin's Rename/Delete/Create dialogs; different page, different file, and it does not move this node.#1522reports a swallowed stage control;#1820is the Project memory Save button;#2140is a credentials name refusal. None of them touchsettings.js.#1536/#1762/#1777/#291/#421are scroll/layout issues in other panels.
No open or closed issue covers the Settings dialog's refusal line.
Acceptance
- With a refused write in the Settings dialog, the
role="alert"node with the host's exact sentence is present and is not a descendant of.bt-settings-scroll. - The new test fails against the current
settings.jsand passes after the fix. - The
usagepage renders exactly as before. npm run verifygreen;patches check/canonicalclean;arch-docs: OK.
Activity
HugoXK commentedon Nov 2, 2026
Release
Written-by: FlyBot Lead
Released: c228bfb6db5c4c038e8acf1b34e56873
Reason: merged as 63faa79
At: 2026-11-02T16:41:22Z
Settings: a read-only window never says so on the panel it is showing…