{"record":{"id":"0d1a658d788c0e18","repo":"temporalio/temporal","slug":"unsupported-partition-kind","errorCode":null,"errorMessage":"unsupported partition kind: ","messagePattern":"unsupported partition kind: ","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"service/matching/physical_task_queue_key.go","lineNumber":144,"sourceCode":"\t\t\treturn nonRootPartitionPrefix + baseName + partitionDelimiter + q.version.versionSet + versionSetDelimiter + strconv.Itoa(p.PartitionId())\n\t\t}\n\n\t\tif len(q.version.deploymentSeriesName) > 0 {\n\t\t\tencodedBuildId := base64.RawURLEncoding.EncodeToString([]byte(q.version.buildId))\n\t\t\tencodedDeploymentName := base64.RawURLEncoding.EncodeToString([]byte(q.version.deploymentSeriesName))\n\t\t\treturn nonRootPartitionPrefix + baseName + partitionDelimiter + encodedDeploymentName + deploymentNameDelimiter + encodedBuildId + buildIdDelimiter + strconv.Itoa(p.PartitionId())\n\t\t} else if len(q.version.buildId) > 0 {\n\t\t\tencodedBuildId := base64.URLEncoding.EncodeToString([]byte(q.version.buildId))\n\t\t\treturn nonRootPartitionPrefix + baseName + partitionDelimiter + encodedBuildId + buildIdDelimiter + strconv.Itoa(p.PartitionId())\n\t\t}\n\n\t\t// unversioned\n\t\tif p.IsRoot() {\n\t\t\treturn baseName\n\t\t}\n\t\treturn nonRootPartitionPrefix + baseName + partitionDelimiter + strconv.Itoa(p.PartitionId())\n\tdefault:\n\t\tpanic(\"unsupported partition kind: \" + p.Kind().String())\n\t}\n}\n\nfunc (q *PhysicalTaskQueueKey) IsVersioned() bool {\n\treturn q.version.IsVersioned()\n}\n\n// Version returns a pointer to the physical queue version key. Caller must not manipulate the\n// returned value.\nfunc (q *PhysicalTaskQueueKey) Version() PhysicalTaskQueueVersion {\n\treturn q.version\n}\n\nfunc (v PhysicalTaskQueueVersion) IsVersioned() bool {\n\treturn v.versionSet != \"\" || v.buildId != \"\"\n}\n\nfunc (v PhysicalTaskQueueVersion) Deployment() *deploymentpb.Deployment {","sourceCodeStart":126,"sourceCodeEnd":162,"githubUrl":"https://github.com/temporalio/temporal/blob/bde624efd13fbd3843654058db6d9c716166318b/service/matching/physical_task_queue_key.go#L126-L162","documentation":"PhysicalTaskQueueKey partition-kind formatting supports only the defined TaskQueuePartition kinds; PersistenceName panics when a key has an unexpected Kind. The empty string in the message means Kind() returned an enum value whose String() is empty — i.e. an unset/zero-valued kind slipped through into partition-name resolution.","triggerScenarios":"getQueueDataByKey receives a PhysicalTaskQueueKey whose partition kind was never set (zero value) or was constructed from persistence/DB data with an out-of-range kind enum, hitting the default branch of the kind switch.","commonSituations":"Task queue data rows in persistence with unrecognized kind values (schema/enum drift between versions); code paths building PhysicalTaskQueueKey literals without setting the kind field; restoring old DB rows after enum renumbering.","solutions":["Find the code path constructing the key and ensure the partition kind is explicitly set from TaskQueueKind (normal/stack) before calling PersistenceName","Check persistence rows for a kind value outside the known enum range and migrate them","Add a constructor/validator that rejects zero-valued kinds early instead of letting them reach PersistenceName"],"exampleFix":"// before\nkey := taskqueue.NewPhysicalTaskQueueKey(p.Partition{})\nname := key.PersistenceName()\n\n// after\np := taskqueue.NewRootPartitionFromTaskQueueInfo(ti)\nkey := taskqueue.NewPhysicalTaskQueueKey(p)\nname := key.PersistenceName()","handlingStrategy":"validation","validationCode":"if p.Kind() == taskqueue.PartitionKindUnspecified {\n\treturn fmt.Errorf(\"partition kind not set before PersistenceName\")\n}","typeGuard":"func validPartitionKind(p taskqueue.Partition) bool {\n\tswitch p.Kind() {\n\tcase taskqueue.PartitionKindNormal, taskqueue.PartitionKindStack:\n\t\treturn true\n\tdefault:\n\t\treturn false\n\t}\n}","tryCatchPattern":"func safePersistenceName(key taskqueue.PhysicalTaskQueueKey) (name string, err error) {\n\tdefer func() {\n\t\tif rec := recover(); rec != nil {\n\t\t\terr = fmt.Errorf(\"partition name panic: %v\", rec)\n\t\t}\n\t}()\n\treturn key.PersistenceName(), nil\n}","preventionTips":["Construct PhysicalTaskQueueKey only via constructors that require a valid partition kind; never use zero-value literals","Validate kind enums read from persistence against the current enum range and migrate out-of-range rows","Keep task queue kind enums in sync across server versions during rolling upgrades"],"tags":["go","panic","task-queue","enum","persistence"],"backgroundTag":"unsupported-enum-value","analyzedSha":"bde624efd13fbd3843654058db6d9c716166318b","analyzedAt":"2026-09-01T07:18:39.080Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}