wavetermdev/waveterm · error
failed to get job: %w
Error message
failed to get job: %w
What it means
GetJobManagerStatus looks up a waveobj.Job in wstore by jobId and returns its manager status. This error wraps any underlying wstore database failure encountered while fetching the job record, distinct from a missing job (which returns JobManagerStatus_Done). It indicates the DBGet call itself failed, e.g. corrupted DB or context cancellation.
Source
Thrown at pkg/jobcontroller/jobcontroller.go:146
}, nil)
wshclient.EventSubCommand(rpcClient, wps.SubscriptionRequest{
Event: wps.Event_ConnChange,
AllScopes: true,
}, nil)
wshclient.EventSubCommand(rpcClient, wps.SubscriptionRequest{
Event: wps.Event_BlockClose,
AllScopes: true,
}, nil)
}
func isJobManagerRunning(job *waveobj.Job) bool {
return job.JobManagerStatus == JobManagerStatus_Running
}
func GetJobManagerStatus(ctx context.Context, jobId string) (string, error) {
job, err := wstore.DBGet[*waveobj.Job](ctx, jobId)
if err != nil {
return "", fmt.Errorf("failed to get job: %w", err)
}
if job == nil {
return JobManagerStatus_Done, nil
}
return job.JobManagerStatus, nil
}
func GetAllJobManagerStatus(ctx context.Context) ([]*wshrpc.JobManagerStatusUpdate, error) {
allJobs, err := wstore.DBGetAllObjsByType[*waveobj.Job](ctx, waveobj.OType_Job)
if err != nil {
return nil, fmt.Errorf("failed to get jobs: %w", err)
}
var statuses []*wshrpc.JobManagerStatusUpdate
for _, job := range allJobs {
statuses = append(statuses, &wshrpc.JobManagerStatusUpdate{
JobId: job.OID,
JobManagerStatus: job.JobManagerStatus,View on GitHub (pinned to a4447c1563)
Solutions
- Log and inspect the wrapped inner error (%w) to identify the wstore failure cause
- Retry GetJobManagerStatus with a fresh, non-canceled context
- Check DB file health/permissions in the wave data directory
- If the job may not exist, treat nil/DBGet failure distinctly and fall back to JobManagerStatus_Done
Example fix
// before
status, err := jobcontroller.GetJobManagerStatus(ctx, jobId)
if err != nil {
return err
}
// after
status, err := jobcontroller.GetJobManagerStatus(ctx, jobId)
if err != nil {
if errors.Is(ctx.Err(), context.Canceled) {
return nil
}
log.Printf("job status lookup failed, defaulting to Done: %v", err)
status = jobcontroller.JobManagerStatus_Done
} Defensive patterns
Strategy: try-catch
Validate before calling
if ctx.Err() != nil {
return errors.New("context already canceled; skip job status lookup")
}
job, _ := wstore.DBGet[*waveobj.Job](ctx, jobId)
if job == nil { /* will be treated as Done, no error */ } Type guard
func jobRecordLoadable(ctx context.Context, jobId string) bool {
return ctx.Err() == nil && jobId != ""
} Try / catch
status, err := jobcontroller.GetJobManagerStatus(ctx, jobId)
if err != nil {
var ctxErr = context.Canceled
if errors.As(err, &ctxErr) { return nil }
log.Printf("status lookup failed: %v", err)
status = jobcontroller.JobManagerStatus_Done
} Prevention
- Always pass a live context and check ctx.Err() before DB calls
- Log the wrapped inner error, not just the outer message
- Handle nil job (Done) and DB failure as separate paths
- Monitor DB health in the wave data directory
When it happens
Trigger: Calling GetJobManagerStatus (directly or via getJobStatus_withlock / Start) with a jobId when wstore.DBGet fails — DB backend I/O error, context canceled/expired, or store not initialized.
Common situations: Wave DB file locked or corrupted; calling from a shutdown path where the context was already canceled; transient disk errors during heavy I/O.
Related errors
- failed to get jobs: %w
- failed to get block: %w
- error getting tab: %w
- error getting client data: %w
- error getting object: %w
AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01).
Data as JSON: /api/errors/2d941006c1574d7c.
Report an issue: GitHub.