temporalio/temporal · error
shard ID must be greater than 0
Error message
shard ID must be greater than 0
What it means
ErrShardIDInvalid (common/persistence/history_task_queue_manager.go:45) states 'shard ID must be greater than 0'. Shard IDs in the history task queue system are 1-based; a zero or negative shard ID cannot map to a queue partition. EnqueueTask (and the queue Invoke path) validates this before touching persistence, and TestHistoryTaskQueueManager_InvalidShardID covers the guard.
Source
Thrown at common/persistence/history_task_queue_manager.go:45
// - ShardID
// - Blob (a serialized task)
ErrMsgDeserializeRawHistoryTask = "failed to deserialize raw history task from task queue"
// ErrMsgDeserializeHistoryTask is returned when the history task cannot be deserialized from the task queue. This
// error is returned when the blob inside the raw task cannot be deserialized.
// Raw Task (a proto):
// - ShardID
// - Blob (a serialized task) <-- when this cannot be deserialized
ErrMsgDeserializeHistoryTask = "failed to deserialize history task blob"
// ErrMsgFailedToParseCategoryID is returned when category id cannot be parsed as an integer value.
ErrMsgFailedToParseCategoryID = "failed to parse category id from queue name"
)
var (
ErrReadTasksNonPositivePageSize = errors.New("page size to read history tasks must be positive")
ErrHistoryTaskBlobIsNil = errors.New("history task from queue has nil blob")
ErrEnqueueTaskRequestTaskIsNil = errors.New("enqueue task request task is nil")
ErrQueueAlreadyExists = errors.New("queue already exists")
ErrShardIDInvalid = errors.New("shard ID must be greater than 0")
ErrInvalidQueueName = errors.New("invalid queue name, expected 4 fields")
)
func NewHistoryTaskQueueManager(
queue QueueV2,
serializer serialization.Serializer,
) *HistoryTaskQueueManagerImpl {
return &HistoryTaskQueueManagerImpl{
queue: queue,
serializer: serializer,
}
}
func (m *HistoryTaskQueueManagerImpl) EnqueueTask(
ctx context.Context,
request *EnqueueTaskRequest,
) (*EnqueueTaskResponse, error) {
if request.Task == nil {View on GitHub (pinned to bde624efd1)
Solutions
- Populate ShardID from the shard context (e.g. shardContext.GetShardID()) before enqueueing
- Add an early validation/log at the producer when shard ID is unavailable
- Fix any 0-based/1-based indexing mismatch in code computing shard IDs
Example fix
// before
mgr.EnqueueTask(ctx, &persistence.EnqueueTaskRequest{ShardID: shardIDFromUnsetStruct}) // 0
// after
if shardID <= 0 {
return fmt.Errorf("invalid shard ID %d for history task enqueue", shardID)
}
mgr.EnqueueTask(ctx, &persistence.EnqueueTaskRequest{ShardID: shardID, Task: task}) Defensive patterns
Strategy: validation
Validate before calling
if req.ShardID <= 0 {
return fmt.Errorf("shard ID must be > 0, got %d", req.ShardID)
}
// safe to call EnqueueTask Try / catch
err := mgr.EnqueueTask(ctx, req)
if err != nil {
if errors.Is(err, persistence.ErrShardIDInvalid) {
logger.Error("invalid shard ID in enqueue request", tag.ShardID(req.ShardID))
return err // programmer error: do not retry
}
return err
} Prevention
- Obtain shard IDs from shardContext.GetShardID(), never hardcode 0
- Remember history queue shard IDs are 1-based
- Validate shard ID at request construction, not at the persistence boundary
- Cover the zero-value request struct case in producer unit tests
When it happens
Trigger: Calling EnqueueTask with request.ShardID <= 0 (typically 0 from an uninitialized request struct).
Common situations: Zero-value request structs; shard ID loaded from config that failed to initialize; off-by-one or 0-based indexing assumptions by new callers; task forwarding logic that lost the shard ID.
Understand the failure class
Background: "must be a positive integer", "cannot be empty", "invalid argument": how invalid-argument errors work across open-source libraries — this error's family across 33 libraries.
Related errors
- page size to read history tasks must be positive
- enqueue task request task is nil
- invalid queue name, expected 4 fields
- history task from queue has nil blob
- queue already exists
AI-assisted analysis of temporalio/temporal@bde624efd1 (2026-09-01).
Data as JSON: /api/errors/14c6fb251ecb5fc7.
Report an issue: GitHub.