dgraph-io/dgraph · error

task ID is invalid: %d

Error message

task ID is invalid: %d

What it means

get rejects task IDs of 0 or math.MaxUint64 with 'task ID is invalid: %d'. These sentinel values cannot result from a real Enqueue (0 is the zero value returned on error; MaxUint64 is reserved), so they indicate a malformed or default-initialized task ID.

Source

Thrown at worker/queue.go:200

	select {
	// t.logMu must be acquired before pushing to t.queue, otherwise the worker might start the
	// task, and won't be able to find it in t.log.
	case t.queue <- task:
		t.log.Set(task.id, newTaskMeta(kind, TaskStatusQueued).uint64())
		return task.id, nil
	default:
		return 0, fmt.Errorf("too many pending tasks, please try again later")
	}
}

// get retrieves metadata for a given task ID.
func (t *tasks) get(id uint64) (TaskMeta, error) {
	if t == nil {
		return 0, fmt.Errorf("task queue hasn't been initialized yet")
	}

	if id == 0 || id == math.MaxUint64 {
		return 0, fmt.Errorf("task ID is invalid: %d", id)
	}
	t.logMu.Lock()
	defer t.logMu.Unlock()
	meta := TaskMeta(t.log.Get(id))
	if meta == 0 {
		return 0, fmt.Errorf("task does not exist or has expired")
	}
	return meta, nil
}

// worker loops forever, running queued tasks one at a time. Any returned errors are logged.
func (t *tasks) worker() {
	shouldCleanup := time.Tick(time.Hour)

	for {
		// If the server is shutting down, return immediately. Else, fetch a task from the queue.
		var task taskRequest
		select {

View on GitHub (pinned to 759e242be6)

Solutions

  1. Capture the task ID only from a successful Enqueue and persist it before polling status
  2. Reject 0/MaxUint64 task IDs at the client boundary with a clear message
  3. If the ID was lost, re-run the backup/export operation to obtain a new task ID

Example fix

// before
meta, _ := tasks.get(id) // id may be 0
// after
if id == 0 || id == math.MaxUint64 {
    return fmt.Errorf("no valid task ID; did Enqueue fail?")
}
meta, err := tasks.get(id)
Defensive patterns

Strategy: validation

Validate before calling

func validID(id uint64) bool { return id != 0 && id != math.MaxUint64 }
if !validID(id) { return fmt.Errorf("task ID %d is not a real task ID", id) }

Type guard

func isRealTaskID(id uint64) bool {
    return id != 0 && id != math.MaxUint64
}

Try / catch

meta, err := tasks.Get(id)
if err != nil && strings.Contains(err.Error(), "task ID is invalid") {
    return fmt.Errorf("task ID %d invalid; only IDs from a successful Enqueue are queryable", id)
}

Prevention

When it happens

Trigger: Calling get/TaskStatus with id == 0 (e.g. the ID from a failed Enqueue) or id == math.MaxUint64 (sentinel/reserved value passed by mistake).

Common situations: Ignoring the error from Enqueue and passing its 0 ID to status polling; a client initializing TaskId to math.MaxUint64 as 'unset' or 'latest'; a serialization bug mapping missing fields to MaxUint64.

Related errors


AI-assisted analysis of dgraph-io/dgraph@759e242be6 (2026-09-01). Data as JSON: /api/errors/31e4b0a5785febea. Report an issue: GitHub.