Symptom
/insights/tasks shows the "No tasks yet" empty state on a bench that has run plenty of tasks. The All sites and All types dropdowns are empty too — they are built from the loaded rows, so they collapse to just "All sites" / "All types".
Cause
Two things combine:
GET /api/v1/tasks returns the 50 most recent tasks.
useTasks then hides fetch-all-app-updates client-side, after that truncation:
// admin/frontend/dashboard/src/composables/tasks/useTasks.js
const HIDDEN_COMMANDS = new Set(['fetch-all-app-updates'])
...
tasks.value = list.filter((task) => !HIDDEN_COMMANDS.has(task.command))
The app-update poller runs roughly every 6 minutes, so it alone produces ~240 tasks a day. On my bench every single one of the 50 returned tasks was a poller run, covering only the last 5 hours:
// fetch('/api/v1/tasks')
{ total: 50,
byCommand: { "fetch-all-app-updates": 50 },
oldest: "2026-08-04T10:49:00Z",
newest: "2026-08-04T16:14:20Z" }
All 50 are hidden, so the list renders empty. The real tasks — backups, migrations, deploys — still exist, they just sit below 50 poller entries.
Why the current approach can't work
Hiding a command the server doesn't know is hidden only holds while the noise is sparse. Any bench left running long enough for the poller to fill one page will show an empty Tasks page. It also silently breaks the site and type filters, because both menus are derived from the loaded rows.
Suggested fix
Move the exclusion server-side so the 50 rows that come back are 50 useful rows — either by excluding the poller from GET /api/v1/tasks by default, or by adding an exclude/command filter the frontend passes. The client-side HIDDEN_COMMANDS set can then go away.
Worth deciding at the same time whether poller runs should be listed at all, or only surfaced somewhere separate.
Notes
- Not a regression:
HIDDEN_COMMANDS predates the current UI work (present on develop, unchanged since the admin/frontend/{dashboard,editor} restructure in 8aa5702).
- Separately,
GET /api/v1/tasks?limit=5 returned 50 rows — the limit parameter looks like it is being ignored on this endpoint.
Symptom
/insights/tasksshows the "No tasks yet" empty state on a bench that has run plenty of tasks. The All sites and All types dropdowns are empty too — they are built from the loaded rows, so they collapse to just "All sites" / "All types".Cause
Two things combine:
GET /api/v1/tasksreturns the 50 most recent tasks.useTasksthen hidesfetch-all-app-updatesclient-side, after that truncation:The app-update poller runs roughly every 6 minutes, so it alone produces ~240 tasks a day. On my bench every single one of the 50 returned tasks was a poller run, covering only the last 5 hours:
All 50 are hidden, so the list renders empty. The real tasks — backups, migrations, deploys — still exist, they just sit below 50 poller entries.
Why the current approach can't work
Hiding a command the server doesn't know is hidden only holds while the noise is sparse. Any bench left running long enough for the poller to fill one page will show an empty Tasks page. It also silently breaks the site and type filters, because both menus are derived from the loaded rows.
Suggested fix
Move the exclusion server-side so the 50 rows that come back are 50 useful rows — either by excluding the poller from
GET /api/v1/tasksby default, or by adding an exclude/command filter the frontend passes. The client-sideHIDDEN_COMMANDSset can then go away.Worth deciding at the same time whether poller runs should be listed at all, or only surfaced somewhere separate.
Notes
HIDDEN_COMMANDSpredates the current UI work (present ondevelop, unchanged since theadmin/frontend/{dashboard,editor}restructure in 8aa5702).GET /api/v1/tasks?limit=5returned 50 rows — thelimitparameter looks like it is being ignored on this endpoint.