{"record":{"id":"2f2d0e65e8942e37","repo":"wavetermdev/waveterm","slug":"failed-to-get-jobs-w","errorCode":null,"errorMessage":"failed to get jobs: %w","messagePattern":"failed to get jobs: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/jobcontroller/jobcontroller.go","lineNumber":157,"sourceCode":"func isJobManagerRunning(job *waveobj.Job) bool {\n\treturn job.JobManagerStatus == JobManagerStatus_Running\n}\n\nfunc GetJobManagerStatus(ctx context.Context, jobId string) (string, error) {\n\tjob, err := wstore.DBGet[*waveobj.Job](ctx, jobId)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"failed to get job: %w\", err)\n\t}\n\tif job == nil {\n\t\treturn JobManagerStatus_Done, nil\n\t}\n\treturn job.JobManagerStatus, nil\n}\n\nfunc GetAllJobManagerStatus(ctx context.Context) ([]*wshrpc.JobManagerStatusUpdate, error) {\n\tallJobs, err := wstore.DBGetAllObjsByType[*waveobj.Job](ctx, waveobj.OType_Job)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to get jobs: %w\", err)\n\t}\n\n\tvar statuses []*wshrpc.JobManagerStatusUpdate\n\tfor _, job := range allJobs {\n\t\tstatuses = append(statuses, &wshrpc.JobManagerStatusUpdate{\n\t\t\tJobId:            job.OID,\n\t\t\tJobManagerStatus: job.JobManagerStatus,\n\t\t})\n\t}\n\n\treturn statuses, nil\n}\n\nfunc GetBlockJobStatus(ctx context.Context, blockId string) (*wshrpc.BlockJobStatusData, error) {\n\tblock, err := wstore.DBGet[*waveobj.Block](ctx, blockId)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to get block: %w\", err)\n\t}","sourceCodeStart":139,"sourceCodeEnd":175,"githubUrl":"https://github.com/wavetermdev/waveterm/blob/a4447c1563b2df285ab89e76c82f91e1a1a49c1e/pkg/jobcontroller/jobcontroller.go#L139-L175","documentation":"GetAllJobManagerStatus retrieves every waveobj.Job via wstore.DBGetAllObjsByType and maps them to JobManagerStatusUpdate entries. This error wraps a failure of the underlying type-scoped DB enumeration, before any per-job processing begins.","triggerScenarios":"Calling GetAllJobManagerStatus when wstore.DBGetAllObjsByType[*waveobj.Job](ctx, OType_Job) fails — DB I/O error, corrupted job records, or canceled context.","commonSituations":"DB corruption affecting the job table; context cancellation during app shutdown; disk full preventing reads.","solutions":["Inspect the wrapped error for the wstore root cause","Retry with a live context","Repair/restore the wave DB if corruption is indicated","Return an empty list instead of failing if statuses are best-effort"],"exampleFix":"// before\nstatuses, err := jobcontroller.GetAllJobManagerStatus(ctx)\nif err != nil {\n\treturn err\n}\n// after\nstatuses, err := jobcontroller.GetAllJobManagerStatus(ctx)\nif err != nil {\n\tlog.Printf(\"failed to enumerate job statuses: %v\", err)\n\tstatuses = nil\n}","handlingStrategy":"fallback","validationCode":"if ctx.Err() != nil {\n\treturn errors.New(\"context canceled; skip enumeration\")\n}","typeGuard":null,"tryCatchPattern":"statuses, err := jobcontroller.GetAllJobManagerStatus(ctx)\nif err != nil {\n\tlog.Printf(\"using empty job status list: %v\", err)\n\tstatuses = []*wshrpc.JobManagerStatusUpdate{}\n}","preventionTips":["Treat status enumeration as best-effort with an empty-list fallback","Check context validity before batch reads","Alert on repeated failures — may indicate DB corruption","Keep wave DB backups"],"tags":["database","wstore","job-controller"],"backgroundTag":"database-read-failed","analyzedSha":"a4447c1563b2df285ab89e76c82f91e1a1a49c1e","analyzedAt":"2026-09-01T15:26:23.972Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}