temporalio/temporal · critical
unsupported partition kind:
Error message
unsupported partition kind:
What it means
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.
Source
Thrown at service/matching/physical_task_queue_key.go:144
return nonRootPartitionPrefix + baseName + partitionDelimiter + q.version.versionSet + versionSetDelimiter + strconv.Itoa(p.PartitionId())
}
if len(q.version.deploymentSeriesName) > 0 {
encodedBuildId := base64.RawURLEncoding.EncodeToString([]byte(q.version.buildId))
encodedDeploymentName := base64.RawURLEncoding.EncodeToString([]byte(q.version.deploymentSeriesName))
return nonRootPartitionPrefix + baseName + partitionDelimiter + encodedDeploymentName + deploymentNameDelimiter + encodedBuildId + buildIdDelimiter + strconv.Itoa(p.PartitionId())
} else if len(q.version.buildId) > 0 {
encodedBuildId := base64.URLEncoding.EncodeToString([]byte(q.version.buildId))
return nonRootPartitionPrefix + baseName + partitionDelimiter + encodedBuildId + buildIdDelimiter + strconv.Itoa(p.PartitionId())
}
// unversioned
if p.IsRoot() {
return baseName
}
return nonRootPartitionPrefix + baseName + partitionDelimiter + strconv.Itoa(p.PartitionId())
default:
panic("unsupported partition kind: " + p.Kind().String())
}
}
func (q *PhysicalTaskQueueKey) IsVersioned() bool {
return q.version.IsVersioned()
}
// Version returns a pointer to the physical queue version key. Caller must not manipulate the
// returned value.
func (q *PhysicalTaskQueueKey) Version() PhysicalTaskQueueVersion {
return q.version
}
func (v PhysicalTaskQueueVersion) IsVersioned() bool {
return v.versionSet != "" || v.buildId != ""
}
func (v PhysicalTaskQueueVersion) Deployment() *deploymentpb.Deployment {View on GitHub (pinned to bde624efd1)
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
Example fix
// before
key := taskqueue.NewPhysicalTaskQueueKey(p.Partition{})
name := key.PersistenceName()
// after
p := taskqueue.NewRootPartitionFromTaskQueueInfo(ti)
key := taskqueue.NewPhysicalTaskQueueKey(p)
name := key.PersistenceName() Defensive patterns
Strategy: validation
Validate before calling
if p.Kind() == taskqueue.PartitionKindUnspecified {
return fmt.Errorf("partition kind not set before PersistenceName")
} Type guard
func validPartitionKind(p taskqueue.Partition) bool {
switch p.Kind() {
case taskqueue.PartitionKindNormal, taskqueue.PartitionKindStack:
return true
default:
return false
}
} Try / catch
func safePersistenceName(key taskqueue.PhysicalTaskQueueKey) (name string, err error) {
defer func() {
if rec := recover(); rec != nil {
err = fmt.Errorf("partition name panic: %v", rec)
}
}()
return key.PersistenceName(), nil
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Unknown task category type: %v
- page size to read history tasks must be positive
- history task from queue has nil blob
- enqueue task request task is nil
- queue already exists
AI-assisted analysis of temporalio/temporal@bde624efd1 (2026-09-01).
Data as JSON: /api/errors/0d1a658d788c0e18.
Report an issue: GitHub.