{"record":{"id":"630bf46dc9dd327d","repo":"temporalio/temporal","slug":"unknown-category-type-v","errorCode":null,"errorMessage":"Unknown category type: %v","messagePattern":"Unknown category type: (.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"service/history/shard/task_key_generator.go","lineNumber":126,"sourceCode":"\t\t}\n\t}\n\n\treturn nil\n}\n\nfunc (a *taskKeyGenerator) peekTaskKey(\n\tcategory tasks.Category,\n) tasks.Key {\n\tswitch category.Type() {\n\tcase tasks.CategoryTypeImmediate:\n\t\treturn tasks.NewImmediateKey(a.nextTaskID)\n\tcase tasks.CategoryTypeScheduled:\n\t\treturn tasks.NewKey(\n\t\t\ta.taskMinScheduledTime,\n\t\t\ta.nextTaskID,\n\t\t)\n\tdefault:\n\t\tpanic(fmt.Sprintf(\"Unknown category type: %v\", category.Type()))\n\t}\n}\n\nfunc (a *taskKeyGenerator) generateTaskKey(\n\tcategory tasks.Category,\n) (tasks.Key, error) {\n\tid, err := a.generateTaskID()\n\tif err != nil {\n\t\treturn tasks.Key{}, err\n\t}\n\n\tswitch category.Type() {\n\tcase tasks.CategoryTypeImmediate:\n\t\treturn tasks.NewImmediateKey(id), nil\n\tcase tasks.CategoryTypeScheduled:\n\t\treturn tasks.NewKey(\n\t\t\ta.taskMinScheduledTime,\n\t\t\tid,","sourceCodeStart":108,"sourceCodeEnd":144,"githubUrl":"https://github.com/temporalio/temporal/blob/bde624efd13fbd3843654058db6d9c716166318b/service/history/shard/task_key_generator.go#L108-L144","documentation":"peekTaskKey computes the next task Key for a category without consuming an ID. It only supports categories of type Immediate and Scheduled; any other CategoryType (e.g. CategoryTypePosterior or a newly added type not yet wired into the key generator) hits the default branch and panics. This is a developer-invariant panic: the category registry accepted the category but the key generator does not know how to key it.","triggerScenarios":"Calling taskKeyGenerator.peekTaskKey(category) with a tasks.Category whose Type() is not CategoryTypeImmediate or CategoryTypeScheduled — usually when adding a new task category in the tasks package without extending peekTaskKey.","commonSituations":"Contributors adding a new task category (e.g. a new priority or posterior category) but forgetting to add a switch case; custom forks introducing category types not present upstream.","solutions":["Add a switch case in peekTaskKey for the new category type and return an appropriate tasks.Key.","Confirm the correct CategoryType was registered for the category in the task category registry (Immediate vs Scheduled).","If the category should not generate keys through this path, refactor the caller to bypass peekTaskKey for that category.","Search the tasks package for the category definition and ensure its Type() is one supported by the shard's key generator."],"exampleFix":"// before\ndefault:\n    panic(fmt.Sprintf(\"Unknown category type: %v\", category.Type()))\n\n// after\ncase tasks.CategoryTypePosterior:\n    return tasks.NewKey(a.taskMinScheduledTime, a.nextTaskID)\ndefault:\n    panic(fmt.Sprintf(\"Unknown category type: %v\", category.Type()))","handlingStrategy":"type-guard","validationCode":"ct := category.Type()\nif ct != tasks.CategoryTypeImmediate && ct != tasks.CategoryTypeScheduled {\n    return fmt.Errorf(\"unsupported category type: %v\", ct)\n}","typeGuard":"func keyableCategory(c tasks.Category) bool {\n    t := c.Type()\n    return t == tasks.CategoryTypeImmediate || t == tasks.CategoryTypeScheduled\n}","tryCatchPattern":null,"preventionTips":["When adding a task category, extend both peekTaskKey and generateTaskKey in the same PR","Add a table-driven test iterating every registered category against the key generator","Prefer explicit CategoryType at registration and document which types the generator supports"],"tags":["history-service","task-key","panic","invariant-violation"],"backgroundTag":"unknown-task-category-type","analyzedSha":"bde624efd13fbd3843654058db6d9c716166318b","analyzedAt":"2026-09-01T07:18:39.080Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}