wavetermdev/waveterm · error

error deleting workspace: %w

Error message

error deleting workspace: %w

What it means

After re-pointing the window to the new workspace, SwitchWorkspace calls DeleteWorkspace on the old workspace; if that delete fails AND the workspace was not actually deleted, this error wraps the underlying cause. Note: if the workspace was deleted despite the error, the error is only printed, not returned (known isolated quirk flagged in the source comment).

Source

Thrown at pkg/wcore/window.go:59

	for _, w := range allWindows {
		if w.WorkspaceId == workspaceId {
			log.Printf("workspace %s already has a window %s, focusing that window\n", workspaceId, w.OID)
			client := wshclient.GetBareRpcClient()
			err = wshclient.FocusWindowCommand(client, w.OID, &wshrpc.RpcOpts{Route: wshutil.ElectronRoute})
			return nil, err
		}
	}
	window.WorkspaceId = workspaceId
	err = wstore.DBUpdate(ctx, window)
	if err != nil {
		return nil, fmt.Errorf("error updating window: %w", err)
	}

	deleted, _, err := DeleteWorkspace(ctx, curWsId, false)
	if err != nil && deleted {
		print(err.Error()) // @jalileh isolated the error for now, curwId/workspace was deleted when this occurs.
	} else if err != nil {
		return nil, fmt.Errorf("error deleting workspace: %w", err)
	}

	if !deleted {
		log.Printf("current workspace %s was not deleted\n", curWsId)
	} else {
		log.Printf("deleted current workspace %s\n", curWsId)
	}

	log.Printf("switching window %s to workspace %s\n", windowId, workspaceId)
	return ws, nil
}

func GetWindow(ctx context.Context, windowId string) (*waveobj.Window, error) {
	window, err := wstore.DBMustGet[*waveobj.Window](ctx, windowId)
	if err != nil {
		log.Printf("error getting window %q: %v\n", windowId, err)
		return nil, err
	}

View on GitHub (pinned to a4447c1563)

Solutions

  1. Read the wrapped %w error to see why DeleteWorkspace failed
  2. Check whether the old workspace still has tabs (DeleteWorkspace only deletes empty/unnamed workspaces per its contract)
  3. Manually inspect the DB for orphaned workspace rows and clean up
  4. Report/fix the known quirk where err+deleted==true is only printed and swallowed

Example fix

// before
deleted, _, err := DeleteWorkspace(ctx, curWsId, false)
if err != nil && deleted {
	print(err.Error())
} else if err != nil {
	return nil, fmt.Errorf("error deleting workspace: %w", err)
}
// after
deleted, _, err := DeleteWorkspace(ctx, curWsId, false)
if err != nil {
	log.Printf("deleting old workspace %s (deleted=%v): %v", curWsId, deleted, err)
	if !deleted {
		return nil, fmt.Errorf("error deleting workspace: %w", err)
	}
}
Defensive patterns

Strategy: try-catch

Validate before calling

ws, err := wcore.GetWorkspace(ctx, curWorkspaceId)
if err == nil && ws != nil {
	// old workspace still present; safe to attempt switch and cleanup
}

Try / catch

ws, err := wcore.SwitchWorkspace(ctx, windowId, workspaceId)
if err != nil {
	if strings.Contains(err.Error(), "error deleting workspace") {
		log.Printf("switch likely succeeded but old workspace cleanup failed: %v", err)
		// schedule cleanup, don't necessarily abort the switch
		return nil
	}
	return err
}

Prevention

When it happens

Trigger: wcore.SwitchWorkspace(ctx, windowId, workspaceId) where DeleteWorkspace(ctx, curWsId, false) returns err != nil and deleted == false — e.g. the old workspace still has tabs/windows blocking deletion and the delete operation itself errors.

Common situations: Old workspace contains dependent blocks/tabs that fail to clean up; concurrent clients mutating the same workspace; DB write error while removing workspace objects after a partial delete.

Related errors


AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01). Data as JSON: /api/errors/71334facd52514dd. Report an issue: GitHub.