{"record":{"id":"91cee30277590434","repo":"wavetermdev/waveterm","slug":"error-finding-tab-for-block-w","errorCode":null,"errorMessage":"error finding tab for block: %w","messagePattern":"error finding tab for block: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/wshrpc/wshserver/wshserver.go","lineNumber":813,"sourceCode":"\treturn &wshrpc.WaveFileInfo{\n\t\tZoneId:    wf.ZoneId,\n\t\tName:      wf.Name,\n\t\tOpts:      wf.Opts,\n\t\tCreatedTs: wf.CreatedTs,\n\t\tSize:      wf.Size,\n\t\tModTs:     wf.ModTs,\n\t\tMeta:      wf.Meta,\n\t}\n}\n\nfunc (ws *WshServer) BlockInfoCommand(ctx context.Context, blockId string) (*wshrpc.BlockInfoData, error) {\n\tblockData, err := wstore.DBMustGet[*waveobj.Block](ctx, blockId)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"error getting block: %w\", err)\n\t}\n\ttabId, err := wstore.DBFindTabForBlockId(ctx, blockId)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"error finding tab for block: %w\", err)\n\t}\n\tworkspaceId, err := wstore.DBFindWorkspaceForTabId(ctx, tabId)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"error finding window for tab: %w\", err)\n\t}\n\tfileList, err := filestore.WFS.ListFiles(ctx, blockId)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"error listing blockfiles: %w\", err)\n\t}\n\tvar fileInfoList []*wshrpc.WaveFileInfo\n\tfor _, wf := range fileList {\n\t\tfileInfoList = append(fileInfoList, waveFileToWaveFileInfo(wf))\n\t}\n\treturn &wshrpc.BlockInfoData{\n\t\tBlockId:     blockId,\n\t\tTabId:       tabId,\n\t\tWorkspaceId: workspaceId,\n\t\tBlock:       blockData,","sourceCodeStart":795,"sourceCodeEnd":831,"githubUrl":"https://github.com/wavetermdev/waveterm/blob/a4447c1563b2df285ab89e76c82f91e1a1a49c1e/pkg/wshrpc/wshserver/wshserver.go#L795-L831","documentation":"After fetching the block, BlockInfoCommand locates its containing tab with wstore.DBFindTabForBlockId. This error wraps failure of that search — the block exists but no tab referencing it could be found, or the lookup errored. It signals store inconsistency between the block and tab collections.","triggerScenarios":"Calling BlockInfoCommand for a blockId whose parent tab was deleted but whose block record lingers; DBFindTabForBlockId returns an internal store error; block id is valid but orphaned during a partial deletion.","commonSituations":"Interrupted block removal leaving orphaned block records; concurrent tab close while BlockInfoCommand runs; restored/migrated store files missing tab entries.","solutions":["Retry the command after the deletion settles — the block is likely mid-removal.","Treat orphaned blocks as inconsistent state: remove the block record or reload workspace state.","Check the wrapped cause to distinguish NotFound (orphaned block) from a DB error.","Refresh the client's workspace/tab data and re-request with a live blockId."],"exampleFix":"// before\ninfo, err := wshclient.BlockInfoCommand(ctx, blockId, nil) // tab already deleted\n// after\nif info, err := wshclient.BlockInfoCommand(ctx, blockId, nil); err != nil {\n    blockId = pickLiveBlockIdFromTab(currentTabId) // choose a block whose tab still exists\n}\n_ = info","handlingStrategy":"fallback","validationCode":"// prefer resolving tab directly instead of through a possibly-orphaned block\ntabId := getTabIdForBlockFromLocalState(blockId)\nif tabId == \"\" {\n    return errors.New(\"block has no live tab; skip BlockInfoCommand\")\n}","typeGuard":"func isOrphanedBlock(err error) bool {\n    return err != nil && strings.Contains(err.Error(), \"error finding tab for block\")\n}","tryCatchPattern":"info, err := wshclient.BlockInfoCommand(ctx, blockId, nil)\nif err != nil {\n    if isOrphanedBlock(err) {\n        // wait for deletion to settle, then retry once\n        time.Sleep(200 * time.Millisecond)\n        info, err = wshclient.BlockInfoCommand(ctx, blockId, nil)\n    }\n    if err != nil { return err }\n}\n_ = info","preventionTips":["Delete block records together with their parent tab atomically","Retry briefly to ride out concurrent tab-close races","Detect orphaned blocks and trigger store cleanup","Resolve tab ids from live workspace state when possible"],"tags":["store","tab","block"],"backgroundTag":"orphaned-block","analyzedSha":"a4447c1563b2df285ab89e76c82f91e1a1a49c1e","analyzedAt":"2026-09-01T15:26:23.972Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}