{"record":{"id":"5924717bfb9d4bd4","repo":"temporalio/temporal","slug":"root-task-queue-partition-has-no-parent","errorCode":null,"errorMessage":"root task queue partition has no parent","messagePattern":"root task queue partition has no parent","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"common/tqid/task_queue_id.go","lineNumber":123,"sourceCode":"\t}\n\n\t// PartitionKey uniquely identifies a task queue partition, to be used in maps.\n\t// Note that task queue kind (sticky vs normal) and normal name for sticky task queues are not\n\t// part of the task queue partition identity.\n\tPartitionKey struct {\n\t\tnamespaceId string\n\t\tname        string\n\t\tpartitionId int\n\t\ttaskType    enumspb.TaskQueueType\n\t}\n)\n\nvar _ Partition = (*NormalPartition)(nil)\nvar _ Partition = (*StickyPartition)(nil)\nvar _ Partition = (*WorkerCommandsPartition)(nil)\n\nvar (\n\tErrNoParent      = errors.New(\"root task queue partition has no parent\")\n\tErrInvalidDegree = errors.New(\"invalid task queue partition branching degree\")\n\tErrNonZeroSticky = errors.New(\"only sticky partitions can not have non-zero partition ID\")\n)\n\n// NewTaskQueueFamily takes a user-provided task queue name (aka family name) and returns a TaskQueueFamily. Returns an\n// error if name looks like a mangled name.\nfunc NewTaskQueueFamily(namespaceId string, name string) (*TaskQueueFamily, error) {\n\tif strings.HasPrefix(name, nonRootPartitionPrefix) {\n\t\treturn nil, serviceerror.NewInvalidArgument(\"task queue family name cannot have prefix /_sys/ \" + name)\n\t}\n\treturn &TaskQueueFamily{\n\t\tnamespaceId: namespaceId,\n\t\tname:        name,\n\t}, nil\n}\n\n// UnsafeTaskQueueFamily returns a TaskQueueFamily object without validating the task queue name.\n// This method should only be used in logs/metrics, not in the server logic (use NewTaskQueueFamily instead).","sourceCodeStart":105,"sourceCodeEnd":141,"githubUrl":"https://github.com/temporalio/temporal/blob/bde624efd13fbd3843654058db6d9c716166318b/common/tqid/task_queue_id.go#L105-L141","documentation":"ErrNoParent is the sentinel error returned when Parent() is called on the root partition of a task-queue family. The root partition (partition 0 of the root task queue) sits at the top of the tqid partition tree, so it has no parent by construction. Test helpers and user-data lookup use it to detect when upward traversal must stop or is invalid.","triggerScenarios":"Calling Parent() on the root NormalPartition of a TaskQueueFamily; userDataFetchSource walking to parents past the root; tests like TestForwardTaskError/TestForwardQueryTaskError/TestForwardPollError exercising forwarding beyond the root partition.","commonSituations":"Partition-index arithmetic that computes partition 0 (root) and still requests a parent; recursive algorithms lacking a root stop condition; forwarding logic trying to route a task/query to a nonexistent parent queue.","solutions":["Stop traversal when Parent() returns ErrNoParent — treat it as the root sentinel via errors.Is(err, tqid.ErrNoParent)","Check partition ID before calling Parent(): skip the call when the partition is the root (partition ID 0 of the root task queue)","Fix partition math so routing only forwards when a parent partition actually exists"],"exampleFix":"// before\nparent, err := partition.Parent()\nrequire.NoError(t, err)\n// after\nparent, err := partition.Parent()\nif errors.Is(err, tqid.ErrNoParent) {\n    return // already at root\n}\nrequire.NoError(t, err)","handlingStrategy":"try-catch","validationCode":"if partition.ID() == 0 && partition.TaskQueue().Parent() == nil /* root family */ {\n    // skip Parent() call\n}","typeGuard":"func hasParent(p tqid.Partition) bool {\n    _, err := p.Parent()\n    return !errors.Is(err, tqid.ErrNoParent)\n}","tryCatchPattern":"parent, err := partition.Parent()\nif errors.Is(err, tqid.ErrNoParent) {\n    return // root reached; stop upward traversal\n}\nif err != nil {\n    return err\n}","preventionTips":["Always check errors.Is(err, tqid.ErrNoParent) to detect the root","Stop parent-walking loops on ErrNoParent","Validate partition IDs before computing parents"],"tags":["tqid","task-queue","partitioning","sentinel-error"],"backgroundTag":"root-partition-has-no-parent","analyzedSha":"bde624efd13fbd3843654058db6d9c716166318b","analyzedAt":"2026-09-01T07:18:39.080Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}