wavetermdev/waveterm · error
error getting block: %w
Error message
error getting block: %w
What it means
DurableShellController.Start begins by loading its Block record with DBMustGet to read blockData.JobId. This error wraps any failure to fetch that Block from the wave store — the block row is missing or the DB read fails.
Source
Thrown at pkg/blockcontroller/durableshellcontroller.go:142
waveobj.MakeORef(waveobj.OType_Block, dsc.BlockId).String(),
},
Data: rtStatus,
})
}
// Start initializes or reconnects to a durable shell for the block.
// Logic:
// - If block has no existing jobId: starts a new job and attaches it
// - If block has existing jobId with running job manager: reconnects to existing job
// - If block has existing jobId with non-running job manager:
// - force=true: detaches old job and starts new one
// - force=false: returns without starting (leaves block unstarted)
//
// After establishing jobId, ensures job connection is active (reconnects if needed)
func (dsc *DurableShellController) Start(ctx context.Context, blockMeta waveobj.MetaMapType, rtOpts *waveobj.RuntimeOpts, force bool) error {
blockData, err := wstore.DBMustGet[*waveobj.Block](ctx, dsc.BlockId)
if err != nil {
return fmt.Errorf("error getting block: %w", err)
}
if conncontroller.IsLocalConnName(dsc.ConnName) {
return fmt.Errorf("durable shell controller requires a remote connection")
}
var jobId string
if blockData.JobId != "" {
status, err := jobcontroller.GetJobManagerStatus(ctx, blockData.JobId)
if err != nil {
return fmt.Errorf("error getting job manager status: %w", err)
}
if status == jobcontroller.JobManagerStatus_Running {
jobId = blockData.JobId
} else if !force {
log.Printf("block %q has jobId %s but manager is not running (status: %s), not starting (force=false)\n", dsc.BlockId, blockData.JobId, status)
return nil
} else {View on GitHub (pinned to a4447c1563)
Solutions
- Confirm the block still exists and hasn't been closed before starting its controller
- Check wavedb integrity / that the app data directory matches the instance
- Treat not-found as benign: skip starting the controller for closed blocks
- Recreate the block if its record was deleted
Example fix
// before
dsc.Start(ctx, meta, rtOpts, true)
// after
if _, err := wstore.DBGet[*waveobj.Block](ctx, dsc.BlockId); err != nil {
return // block gone; don't start
}
dsc.Start(ctx, meta, rtOpts, true) Defensive patterns
Strategy: validation
Validate before calling
if _, err := wstore.DBGet[*waveobj.Block](ctx, dsc.BlockId); err != nil {
return // block absent; do not start controller
} Try / catch
if err := dsc.Start(ctx, meta, rtOpts, true); err != nil {
if strings.Contains(err.Error(), "error getting block") { return nil } // treat as closed
} Prevention
- Stop durable shell controllers when their block is closed
- Avoid starting controllers for blocks pending deletion
- Verify wavedb path/data directory before launch
When it happens
Trigger: Start is called on a controller whose BlockId no longer exists in the store (block closed/deleted concurrently) or the wavedb read errors.
Common situations: Block closed while a start was in flight; workspace deleted; DB corruption or a mismatched data directory after moving app data.
Related errors
- error getting block: %w
- failed to get block: %w
- block not found: %s
- error getting window: %w
- error getting workspace: %w
AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01).
Data as JSON: /api/errors/ea822c20207a3628.
Report an issue: GitHub.