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
Once a workspace holds a Dashboard the UI cannot reach, a saved query that
Dashboard references can become permanently undeletable, with a diagnostic
the user has no way to act on.
Only dashboards[0] — the compatibility Dashboard — is reachable in the UI;
there is no selector, tree, or route parameter for the others yet.
Suppose dashboards[1] has a tile referencing saved query p1, and dashboards[0] does not.
Delete p1 from the ★ Queries list.
deleteSaved (src/state.ts) correctly carries the whole Dashboard collection
into its candidate, whole-workspace validation
(validateDashboardCollectionSemantics) correctly rejects the candidate with dashboard-tile-query-missing at dashboards[1].tiles[0].queryId, and src/ui/saved-history.ts toasts "Couldn't delete: Tile references unknown
saved query …".
Nothing is corrupted — the atomicity contract holds exactly as specified. The
problem is that no UI can reach dashboards[1] to remove that tile, so the
delete can never succeed. The same dead-end applies to any commit that would
dangle a hidden reference, e.g. changing a query's dashboard.role in the Spec
editor.
Why it is new
Before #424 the workspace held zero or one Dashboard, so the rejecting
Dashboard was always the visible one and the user could always repair it by
unstarring the query or deleting the tile. #424's storage change is what makes
an unreachable Dashboard possible, and the owner-approved import-all decision
is what makes one reachable in practice.
Why it is deferred, not fixed here
#424 is explicitly scoped as "storage, validation, repository, migration, and
internal API foundation only", with "Dashboard selector, tabs, dropdown, or
navigation UI" and "creating, deleting, duplicating, renaming, or reordering
Dashboards in the UI" as stated non-goals. The fix needs a surface that can
address a non-compatibility Dashboard, which is exactly what #425 (selection
state) and #426 (Dashboard tree) introduce, and #429 (panel/filter delete
actions) makes repairable.
Suggested resolution
Fold into the #430 programme rather than fixing standalone. Once #425/#426
land, either:
let the delete diagnostic name the offending Dashboard and offer to navigate
to it (the diagnostic already carries resource = the Dashboard id and an
indexed dashboards[i] path), or
offer the existing remove-affected-tiles repair from src/dashboard/application/saved-query-mutation.ts across the whole
collection — note that planner is written for exactly this and still has no
production caller.
Until then the exposure is limited to workspaces created by importing a
multi-Dashboard bundle; nothing the app itself authors can produce one.
Summary
Once a workspace holds a Dashboard the UI cannot reach, a saved query that
Dashboard references can become permanently undeletable, with a diagnostic
the user has no way to act on.
How to reach it
Dashboards. Since Introduce StoredWorkspaceV3 with a dashboard collection and no UI change #424 every bundled Dashboard is imported (in file order),
so
workspace.dashboardsnow has more than one entry.dashboards[0]— the compatibility Dashboard — is reachable in the UI;there is no selector, tree, or route parameter for the others yet.
dashboards[1]has a tile referencing saved queryp1, anddashboards[0]does not.p1from the ★ Queries list.deleteSaved(src/state.ts) correctly carries the whole Dashboard collectioninto its candidate, whole-workspace validation
(
validateDashboardCollectionSemantics) correctly rejects the candidate withdashboard-tile-query-missingatdashboards[1].tiles[0].queryId, andsrc/ui/saved-history.tstoasts "Couldn't delete: Tile references unknownsaved query …".
Nothing is corrupted — the atomicity contract holds exactly as specified. The
problem is that no UI can reach
dashboards[1]to remove that tile, so thedelete can never succeed. The same dead-end applies to any commit that would
dangle a hidden reference, e.g. changing a query's
dashboard.rolein the Speceditor.
Why it is new
Before #424 the workspace held zero or one Dashboard, so the rejecting
Dashboard was always the visible one and the user could always repair it by
unstarring the query or deleting the tile. #424's storage change is what makes
an unreachable Dashboard possible, and the owner-approved import-all decision
is what makes one reachable in practice.
Why it is deferred, not fixed here
#424 is explicitly scoped as "storage, validation, repository, migration, and
internal API foundation only", with "Dashboard selector, tabs, dropdown, or
navigation UI" and "creating, deleting, duplicating, renaming, or reordering
Dashboards in the UI" as stated non-goals. The fix needs a surface that can
address a non-compatibility Dashboard, which is exactly what #425 (selection
state) and #426 (Dashboard tree) introduce, and #429 (panel/filter delete
actions) makes repairable.
Suggested resolution
Fold into the #430 programme rather than fixing standalone. Once #425/#426
land, either:
to it (the diagnostic already carries
resource= the Dashboard id and anindexed
dashboards[i]path), orremove-affected-tilesrepair fromsrc/dashboard/application/saved-query-mutation.tsacross the wholecollection — note that planner is written for exactly this and still has no
production caller.
Until then the exposure is limited to workspaces created by importing a
multi-Dashboard bundle; nothing the app itself authors can produce one.
Reference
src/state.ts—deleteSaved/candidateFromsrc/workspace/stored-workspace.ts—validateStoredWorkspaceDocumentsrc/ui/saved-history.ts— the failure toastsrc/dashboard/application/saved-query-mutation.ts— the unused repair plannerFound during the #424 review; filed rather than folded into that PR.