You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Scheduled tasks page stays on Loading…: the schedule list is neither readable by a signed-in actor nor scoped to one #2111
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: fa1c3f8bd1d84364bc5baf29a0b87068
Branch: dev/2-schedules-read-scope
Base: 4d4b171
At: 2026-11-02T04:04:15Z
What the user sees
On a machine where an account has been set up, opening Settings → Scheduled tasks shows Loading… and never anything else. The same read feeds the Bot details panel, the group-chat details panel and the schedule summary row, so those sections go blank too — and no error is shown anywhere, so there is nothing to click and nothing to read.
Where it comes from (live 4d4b171c)
The page asks for the list with no body: core/src/client/index.js:627 (schedules: () => call('schedules')) → core/src/client/api.js:21 sends payload: payload ?? null.
The host routes that call like a write: core/src/host/authz.js:285 puts schedules in the schedule-* branch, whose tail is requireSession(body?.sessionId) (:298). With no body there is no session id, so the read is denied.
The client swallows the denial: core/src/client/schedules.js:31 (.catch(() => {})) under a 30 s poll (:14), and a null view renders the placeholder at :334.
Scope of the read is the second half of the same defect: core/src/host/schedules.js:640 (schedules: () => schedulesView()) never looks at the actor, and schedulesView() (:403) filters only by known(owner) — the read path does not check the actor at all.
Fix direction
Treat schedules as a read endpoint the way projects is treated: allowed for any signed-in actor, not gated on a sessionId in the body.
Scope the view to the actor: schedulesView() takes the actor and skips rows it does not own, using the predicates the module already has (ownedByActor:186, sourceOf:194).
Leave the write endpoints (schedule-create/update/pause/resume/retry/delete) on their current sessionId gate.
Testable acceptance
With a member session and a null body, the list read succeeds instead of being denied.
With two owners, the list a signed-in actor receives contains only that actor's entries — no other owner's title, prompt or session id.
A failed read is not silent: whatever the page does when the read fails, it must not present the failure as "still loading".
How it was found
Probe against a real /api/bot route and the real authz.js, with a fake schedule catalog as the data source (two owners, one Bot each) — PAGE REQUEST is denied, and the denial is then swallowed by the client. Not reproduced on a running instance: that instance has no member signed in yet, which is exactly the condition this needs.
Checked for duplicates: no open issue covers this; the nearest closed ones are #2035 / #2039 / #2040 (task list visibility and copy reachability in details panels) and #1321 / #1336 (write-side scoping of copy and edit) — different root cause, none of them touch the read endpoint's gate.
Activity
HugoXK commentedon Nov 2, 2026
Release
Written-by: FlyBot Lead
Released: fa1c3f8bd1d84364bc5baf29a0b87068
Reason: fixed by #2112, merged 2026-11-02T04:43:29Z (5a8efc1)
At: 2026-11-02T04:47:23Z