{"record":{"id":"c5a7c4e8d02707a1","repo":"temporalio/temporal","slug":"unknown-task-status-v","errorCode":null,"errorMessage":"unknown task status: %v","messagePattern":"unknown task status: (.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"service/worker/scanner/executor/executor.go","lineNumber":137,"sourceCode":"\n\t\tstatus := task.Run()\n\t\tswitch status {\n\t\tcase TaskStatusDone:\n\t\t\te.outstanding.Add(-1)\n\t\t\tmetrics.ExecutorTasksDoneCount.With(e.metricsHandler).Record(1)\n\t\tcase TaskStatusDefer:\n\t\t\tif e.runQ.deferredCount() < e.maxDeferred {\n\t\t\t\te.runQ.addAndDefer(task)\n\t\t\t\tmetrics.ExecutorTasksDeferredCount.With(e.metricsHandler).Record(1)\n\t\t\t} else {\n\t\t\t\te.outstanding.Add(-1)\n\t\t\t\tmetrics.ExecutorTasksDroppedCount.With(e.metricsHandler).Record(1)\n\t\t\t}\n\t\tcase TaskStatusErr:\n\t\t\te.outstanding.Add(-1)\n\t\t\tmetrics.ExecutorTasksErrCount.With(e.metricsHandler).Record(1)\n\t\tdefault:\n\t\t\tpanic(fmt.Sprintf(\"unknown task status: %v\", status))\n\t\t}\n\t}\n}\n\nfunc (e *fixedPoolExecutor) alive() bool {\n\treturn e.status.Load() == common.DaemonStatusStarted\n}\n","sourceCodeStart":119,"sourceCodeEnd":145,"githubUrl":"https://github.com/temporalio/temporal/blob/bde624efd13fbd3843654058db6d9c716166318b/service/worker/scanner/executor/executor.go#L119-L145","documentation":"The scanner's fixed-pool executor panics when a submitted task reports a status value the executor's result switch doesn't recognize. TaskStatus is an internal enum; this panic guards against a new status being added without updating the executor loop.","triggerScenarios":"Raised in the worker loop of fixedPoolExecutor (service/worker/scanner/executor/executor.go:137) when a task's result status is not TaskStatusCompleted, TaskStatusErr, or the other handled values — typically after code changes introduce a new TaskStatus variant not wired into the executor.","commonSituations":"A developer adds a new task status (e.g. a 'skipped' or 'timeout' status) to the scanner tasks but forgets the executor's switch; mixing versions of task implementations with an older executor.","solutions":["Add a case for the unexpected status in the executor's result switch","Ensure all scanner task implementations return only statuses handled by the executor","Roll back or align task/executor code versions if a partial deploy introduced the new status"],"exampleFix":"// before\ncase TaskStatusErr:\n    e.outstanding.Add(-1)\n    metrics.ExecutorTasksErrCount.With(e.metricsHandler).Record(1)\ndefault:\n    panic(fmt.Sprintf(\"unknown task status: %v\", status))\n// after\ncase TaskStatusErr:\n    e.outstanding.Add(-1)\n    metrics.ExecutorTasksErrCount.With(e.metricsHandler).Record(1)\ncase TaskStatusTimeout: // newly added status\n    e.outstanding.Add(-1)\n    metrics.ExecutorTasksErrCount.With(e.metricsHandler).Record(1)\ndefault:\n    e.logger.Error(\"unknown task status\", tag.Status(int(status)))\n    e.outstanding.Add(-1)","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"func isHandledStatus(s TaskStatus) bool {\n    switch s {\n    case TaskStatusCompleted, TaskStatusErr, TaskStatusPending:\n        return true\n    }\n    return false\n}","tryCatchPattern":null,"preventionTips":["When adding a TaskStatus variant, search for the executor's result switch and update it in the same change","Add a unit test that exercises every TaskStatus value through the executor","Avoid partial deploys mixing new task implementations with old executor binaries"],"tags":["panic","internal-invariant","scanner","worker"],"backgroundTag":"unhandled-enum-case","analyzedSha":"bde624efd13fbd3843654058db6d9c716166318b","analyzedAt":"2026-09-01T07:18:39.080Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}