wavetermdev/waveterm · error
error getting new workspace: %w
Error message
error getting new workspace: %w
What it means
SwitchWorkspace first loads the target workspace with GetWorkspace before switching the window to it. This error wraps any failure of that lookup — the workspace ID does not resolve to an existing Workspace object, or the DB read failed. The window is left unchanged.
Source
Thrown at pkg/wcore/window.go:25
"context"
"fmt"
"log"
"github.com/google/uuid"
"github.com/wavetermdev/waveterm/pkg/eventbus"
"github.com/wavetermdev/waveterm/pkg/util/utilfn"
"github.com/wavetermdev/waveterm/pkg/waveobj"
"github.com/wavetermdev/waveterm/pkg/wshrpc"
"github.com/wavetermdev/waveterm/pkg/wshrpc/wshclient"
"github.com/wavetermdev/waveterm/pkg/wshutil"
"github.com/wavetermdev/waveterm/pkg/wstore"
)
func SwitchWorkspace(ctx context.Context, windowId string, workspaceId string) (*waveobj.Workspace, error) {
log.Printf("SwitchWorkspace %s %s\n", windowId, workspaceId)
ws, err := GetWorkspace(ctx, workspaceId)
if err != nil {
return nil, fmt.Errorf("error getting new workspace: %w", err)
}
window, err := GetWindow(ctx, windowId)
if err != nil {
return nil, fmt.Errorf("error getting window: %w", err)
}
curWsId := window.WorkspaceId
if curWsId == workspaceId {
return nil, nil
}
allWindows, err := wstore.DBGetAllObjsByType[*waveobj.Window](ctx, waveobj.OType_Window)
if err != nil {
return nil, fmt.Errorf("error getting all windows: %w", err)
}
for _, w := range allWindows {
if w.WorkspaceId == workspaceId {
log.Printf("workspace %s already has a window %s, focusing that window\n", workspaceId, w.OID)View on GitHub (pinned to a4447c1563)
Solutions
- Refresh the workspace list (wstore DBGetObjsByType Workspace) and call SwitchWorkspace with a currently-existing workspaceId
- Validate the workspaceId is a non-empty valid UUID and exists before calling
- Handle the not-found case in the caller: fall back to the window's current workspace or the default workspace
- Check the wrapped cause: if it is a DB error (not not-found), investigate the database rather than the ID
Example fix
// before
ws, _ := wclient.SwitchWorkspace(ctx, winId, staleWsId)
// after
wsList, _ := wcore.ListWorkspaces(ctx)
if !containsWorkspace(wsList, wsId) {
wsId = wsList[0].OID // fall back to first existing workspace
}
ws, err := wclient.SwitchWorkspace(ctx, winId, wsId) Defensive patterns
Strategy: validation
Validate before calling
_, err := wcore.GetWorkspace(ctx, workspaceId)
if err != nil {
// resolve a fresh workspace list before switching
return fmt.Errorf("workspace %s unavailable: %w", workspaceId, err)
} Type guard
func workspaceExists(ctx context.Context, id string) bool {
_, err := wcore.GetWorkspace(ctx, id)
return err == nil
} Try / catch
ws, err := wcore.SwitchWorkspace(ctx, winId, wsId)
if err != nil {
if strings.Contains(err.Error(), "getting new workspace") {
wsList, _ := wcore.ListWorkspaces(ctx)
if len(wsList) > 0 { ws, err = wcore.SwitchWorkspace(ctx, winId, wsList[0].OID) }
}
} Prevention
- Re-fetch the workspace list instead of trusting cached IDs
- Treat workspace deletion events as invalidating stored selections
- Validate workspaceId is a non-empty UUID before calling
- Fall back to the default workspace on not-found
When it happens
Trigger: Calling SwitchWorkspace(ctx, windowId, workspaceId) with a workspaceId that is not a valid/existing workspace OID (returns not-found through GetWorkspace), a stale/deleted workspace ID from the frontend, or a DB read error.
Common situations: Frontend holds a cached workspace list and the workspace was deleted in another window/process; malformed workspaceId passed over RPC; stale bookmarks or startup-restore referencing a removed workspace.
Related errors
- error getting window: %w
- error updating workspace: %w
- error getting workspace: %w
- error deleting workspace: %w
- workspace %s not found: %w
AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01).
Data as JSON: /api/errors/723c2aafdd3f0ad4.
Report an issue: GitHub.