{"record":{"id":"4444d182a99f9936","repo":"temporalio/temporal","slug":"invalid-queue-name-expected-4-fields","errorCode":null,"errorMessage":"invalid queue name, expected 4 fields","messagePattern":"invalid queue name, expected 4 fields","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"common/persistence/history_task_queue_manager.go","lineNumber":46,"sourceCode":"\t//\t- Blob (a serialized task)\n\tErrMsgDeserializeRawHistoryTask = \"failed to deserialize raw history task from task queue\"\n\t// ErrMsgDeserializeHistoryTask is returned when the history task cannot be deserialized from the task queue. This\n\t// error is returned when the blob inside the raw task cannot be deserialized.\n\t//  Raw Task (a proto):\n\t//\t- ShardID\n\t//\t- Blob (a serialized task) <-- when this cannot be deserialized\n\tErrMsgDeserializeHistoryTask = \"failed to deserialize history task blob\"\n\t// ErrMsgFailedToParseCategoryID is returned when category id cannot be parsed as an integer value.\n\tErrMsgFailedToParseCategoryID = \"failed to parse category id from queue name\"\n)\n\nvar (\n\tErrReadTasksNonPositivePageSize = errors.New(\"page size to read history tasks must be positive\")\n\tErrHistoryTaskBlobIsNil         = errors.New(\"history task from queue has nil blob\")\n\tErrEnqueueTaskRequestTaskIsNil  = errors.New(\"enqueue task request task is nil\")\n\tErrQueueAlreadyExists           = errors.New(\"queue already exists\")\n\tErrShardIDInvalid               = errors.New(\"shard ID must be greater than 0\")\n\tErrInvalidQueueName             = errors.New(\"invalid queue name, expected 4 fields\")\n)\n\nfunc NewHistoryTaskQueueManager(\n\tqueue QueueV2,\n\tserializer serialization.Serializer,\n) *HistoryTaskQueueManagerImpl {\n\treturn &HistoryTaskQueueManagerImpl{\n\t\tqueue:      queue,\n\t\tserializer: serializer,\n\t}\n}\n\nfunc (m *HistoryTaskQueueManagerImpl) EnqueueTask(\n\tctx context.Context,\n\trequest *EnqueueTaskRequest,\n) (*EnqueueTaskResponse, error) {\n\tif request.Task == nil {\n\t\treturn nil, ErrEnqueueTaskRequestTaskIsNil","sourceCodeStart":28,"sourceCodeEnd":64,"githubUrl":"https://github.com/temporalio/temporal/blob/bde624efd13fbd3843654058db6d9c716166318b/common/persistence/history_task_queue_manager.go#L28-L64","documentation":"ErrInvalidQueueName (common/persistence/history_task_queue_manager.go:46) is returned by GetHistoryTaskQueueCategoryID when a queue name cannot be parsed into the expected 4 fields from which the task category ID is extracted. Queue names encode category, shard, and other identity components; a malformed name means the caller passed a queue identifier the system did not create, or the naming format changed between versions.","triggerScenarios":"Calling GetHistoryTaskQueueCategoryID with a queue name that does not split into exactly 4 fields (wrong separator, missing components, or a queue name built by a different/incompatible writer).","commonSituations":"Hand-constructed queue names in tools/tests; queue names persisted by an older server version being read by a newer one (format change); copying names with typos or extra separators; cross-cluster queue name reuse.","solutions":["Construct the queue name using the library's queue-name builder/format instead of hand-writing it","Check the persisted queue name for version skew and migrate/recreate queues created by incompatible versions","Log the offending name and verify it has exactly 4 separator-delimited fields before parsing"],"exampleFix":"// before\ncategoryID, err := persistence.GetHistoryTaskQueueCategoryID(\"history-task-queue-12\") // 3 fields\n// after\nname := persistence.GetHistoryTaskQueueName(category, shardID, /*expected fields*/) // build via helpers\nif strings.Count(name, separator) != 3 {\n    return fmt.Errorf(\"malformed queue name %q\", name)\n}\ncategoryID, err := persistence.GetHistoryTaskQueueCategoryID(name)","handlingStrategy":"validation","validationCode":"parts := strings.Split(queueName, separator)\nif len(parts) != 4 {\n    return fmt.Errorf(\"queue name %q must have 4 fields, got %d\", queueName, len(parts))\n}\n// safe to call GetHistoryTaskQueueCategoryID","typeGuard":null,"tryCatchPattern":"categoryID, err := persistence.GetHistoryTaskQueueCategoryID(queueName)\nif err != nil {\n    if strings.Contains(err.Error(), \"invalid queue name, expected 4 fields\") {\n        logger.Error(\"malformed history task queue name\", tag.WorkflowQueueName(queueName))\n        return err // do not retry: deterministic parse failure\n    }\n    return err\n}","preventionTips":["Build queue names with the library's name-formatter helpers, never by hand","Bump/migrate queue names when upgrading across server versions with format changes","Validate queue names parsed from persistence before use in tools/scripts","Add a round-trip test: format then parse for every category/shard combination"],"tags":["go","persistence","task-queue","parsing","invalid-argument"],"backgroundTag":"invalid-queue-name","analyzedSha":"bde624efd13fbd3843654058db6d9c716166318b","analyzedAt":"2026-09-01T07:18:39.080Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}