wavetermdev/waveterm · error
error getting block: %w
Error message
error getting block: %w
What it means
ShellController.Start fetches the block record from the wave store (wstore.DBMustGet) before running the shell. If the block cannot be read from the database it cannot be started. This is a local persistence/read failure, independent of any remote connection.
Source
Thrown at pkg/blockcontroller/shellcontroller.go:89
func MakeShellController(tabId string, blockId string, controllerType string, connName string) Controller {
return &ShellController{
Lock: &sync.Mutex{},
ControllerType: controllerType,
TabId: tabId,
BlockId: blockId,
ConnName: connName,
ProcStatus: Status_Init,
RunLock: &atomic.Bool{},
}
}
// Implement Controller interface methods
func (sc *ShellController) Start(ctx context.Context, blockMeta waveobj.MetaMapType, rtOpts *waveobj.RuntimeOpts, force bool) error {
// Get the block data
blockData, err := wstore.DBMustGet[*waveobj.Block](ctx, sc.BlockId)
if err != nil {
return fmt.Errorf("error getting block: %w", err)
}
// Use the existing run method which handles all the start logic
go sc.run(ctx, blockData, blockData.Meta, rtOpts, force)
return nil
}
func (sc *ShellController) Stop(graceful bool, newStatus string, destroy bool) {
sc.Lock.Lock()
defer sc.Lock.Unlock()
if sc.ShellProc == nil || sc.ProcStatus == Status_Done || sc.ProcStatus == Status_Init {
if newStatus != sc.ProcStatus {
sc.ProcStatus = newStatus
sc.sendUpdate_nolock()
}
return
}View on GitHub (pinned to a4447c1563)
Solutions
- Confirm the BlockId exists (query the block via the store/API) before Start.
- Re-create the block/tab if it was deleted; discard the stale controller.
- Check the local database health (file permissions, disk space).
- Retry after the store finishes initializing at app startup.
Example fix
// before
_, err := wstore.DBGet[*waveobj.Block](ctx, blockId) // ok == false, still call Start
err = sc.Start(ctx, meta, rtOpts, false) // "error getting block"
// after
if _, err := wstore.DBGet[*waveobj.Block](ctx, sc.BlockId); err != nil {
return err // don't attempt Start on a missing block
}
return sc.Start(ctx, meta, rtOpts, false) Defensive patterns
Strategy: validation
Validate before calling
if _, err := wstore.DBGet[*waveobj.Block](ctx, sc.BlockId); err != nil {
return fmt.Errorf("block %s does not exist, skipping start", sc.BlockId)
} Type guard
func blockExists(ctx context.Context, blockId string) bool {
_, err := wstore.DBGet[*waveobj.Block](ctx, blockId)
return err == nil
} Try / catch
if err := sc.Start(ctx, meta, rtOpts, false); err != nil && strings.Contains(err.Error(), "error getting block") {
// block is gone; tear down the controller instead of retrying
return err
} Prevention
- Verify block existence before constructing a controller
- Handle concurrent block deletion events
- Keep the local store healthy (disk space, permissions)
When it happens
Trigger: DBMustGet[*waveobj.Block] errors: the BlockId does not exist (block deleted), the store is not initialized, database I/O failure, or the id passed to the controller is stale/incorrect.
Common situations: Starting a controller for a block that was closed/deleted concurrently; corrupted or locked local database; calling Start with a fabricated or typo'd block id in tests or plugins.
Related errors
- error getting block: %w
- no job attached to controller
- no shell input chan
- failed to get block: %w
- no vdom context block id
AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01).
Data as JSON: /api/errors/93f0701769a13f9c.
Report an issue: GitHub.