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
- Capture the task ID only from a successful Enqueue and persist it before polling status
- Reject 0/MaxUint64 task IDs at the client boundary with a clear message
- 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
- Only use task IDs returned from a successful (err == nil) Enqueue
- Treat 0 and MaxUint64 as sentinel values, never real IDs
- Log the task ID at creation time so it can be recovered
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
- invalid task ID: %#x
- NQuad failed sanity check. Subject: %q, Predicate: %q, Objec
- empty variable name in function call
- empty facetKeys not allowed
- No value found
AI-assisted analysis of dgraph-io/dgraph@759e242be6 (2026-09-01).
Data as JSON: /api/errors/31e4b0a5785febea.
Report an issue: GitHub.