wavetermdev/waveterm · error
error deleting workspace: %w
Error message
error deleting workspace: %w
What it means
WorkspaceService.DeleteWorkspace deletes a workspace via wcore.DeleteWorkspace(ctx, workspaceId, true) and wraps failures with this error — unless the workspace has claimable windows, in which case the claimable id is returned instead (no error). The wrapped error typically means the workspace id was not found or the deletion/persistence step failed.
Source
Thrown at pkg/service/workspaceservice/workspaceservice.go:101
return ws, nil
}
func (svc *WorkspaceService) DeleteWorkspace_Meta() tsgenmeta.MethodMeta {
return tsgenmeta.MethodMeta{
ArgNames: []string{"workspaceId"},
}
}
func (svc *WorkspaceService) DeleteWorkspace(workspaceId string) (waveobj.UpdatesRtnType, string, error) {
ctx, cancelFn := context.WithTimeout(context.Background(), DefaultTimeout)
defer cancelFn()
ctx = waveobj.ContextWithUpdates(ctx)
deleted, claimableWorkspace, err := wcore.DeleteWorkspace(ctx, workspaceId, true)
if claimableWorkspace != "" {
return nil, claimableWorkspace, nil
}
if err != nil {
return nil, claimableWorkspace, fmt.Errorf("error deleting workspace: %w", err)
}
if !deleted {
return nil, claimableWorkspace, nil
}
updates := waveobj.ContextGetUpdatesRtn(ctx)
go func() {
defer func() {
panichandler.PanicHandler("WorkspaceService:DeleteWorkspace:SendUpdateEvents", recover())
}()
wps.Broker.SendUpdateEvents(updates)
}()
return updates, claimableWorkspace, nil
}
func (svc *WorkspaceService) ListWorkspaces() (waveobj.WorkspaceList, error) {
ctx, cancelFn := context.WithTimeout(context.Background(), DefaultTimeout)
defer cancelFn()
return wcore.ListWorkspaces(ctx)View on GitHub (pinned to a4447c1563)
Solutions
- Handle the claimableWorkspace return value first — the call may legitimately return no error and no deletion when windows must be claimed elsewhere
- Unwrap the %w error: for not-found, refresh the workspace list and treat the workspace as already deleted; for DB errors, retry once after checking DB health
- Guard UI delete actions against duplicate submissions (disable after first click / dedupe by id in flight)
- Re-fetch workspaces after any failed delete before retrying with the same id
Defensive patterns
Strategy: try-catch
Validate before calling
const exists = await WorkspaceService.GetWorkspace(workspaceId).catch(() => null);
if (!exists) throw new Error(`workspace ${workspaceId} already deleted`); Type guard
function isDeletableWorkspace(ws: waveobj.Workspace | null | undefined, id: string): ws is waveobj.Workspace {
return ws != null && ws.OID === id;
} Try / catch
claimable, cw, err := WorkspaceService.DeleteWorkspace(ctx, workspaceId)
if err != nil {
if strings.Contains(err.Error(), "not found") { return refreshWorkspaces() }
return fmt.Errorf("delete workspace: %w", err)
}
if claimable == nil && cw != "" { /* windows need claiming first; surface to user */ } Prevention
- Handle the claimableWorkspace return value (windows must be re-homed) before assuming deletion failed
- Deduplicate delete submissions so the same id is never deleted twice concurrently
- Refresh the workspace list after any delete attempt, success or failure
- Process bulk deletions against a freshly-fetched id list, not a cached one
When it happens
Trigger: DeleteWorkspace called with a nonexistent or already-deleted workspaceId, or wcore's deletion (object removal, update recording) fails due to DB error or timeout; concurrent deletion from another client.
Common situations: Double-click/double-submit of a delete action deleting the same workspace twice; frontend workspace list stale after another window deleted the workspace; DB failure mid-deletion leaving partial state; scripts iterating a cached list of workspace ids.
Related errors
- error updating workspace: %w
- error getting workspace: %w
- error getting new workspace: %w
- workspace %s not found: %w
- workspace already deleted %w
AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01).
Data as JSON: /api/errors/17d980cc6bfdfaa9.
Report an issue: GitHub.