{"record":{"id":"31e4b0a5785febea","repo":"dgraph-io/dgraph","slug":"task-id-is-invalid-d","errorCode":null,"errorMessage":"task ID is invalid: %d","messagePattern":"task ID is invalid: (.+?)","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"worker/queue.go","lineNumber":200,"sourceCode":"\tselect {\n\t// t.logMu must be acquired before pushing to t.queue, otherwise the worker might start the\n\t// task, and won't be able to find it in t.log.\n\tcase t.queue <- task:\n\t\tt.log.Set(task.id, newTaskMeta(kind, TaskStatusQueued).uint64())\n\t\treturn task.id, nil\n\tdefault:\n\t\treturn 0, fmt.Errorf(\"too many pending tasks, please try again later\")\n\t}\n}\n\n// get retrieves metadata for a given task ID.\nfunc (t *tasks) get(id uint64) (TaskMeta, error) {\n\tif t == nil {\n\t\treturn 0, fmt.Errorf(\"task queue hasn't been initialized yet\")\n\t}\n\n\tif id == 0 || id == math.MaxUint64 {\n\t\treturn 0, fmt.Errorf(\"task ID is invalid: %d\", id)\n\t}\n\tt.logMu.Lock()\n\tdefer t.logMu.Unlock()\n\tmeta := TaskMeta(t.log.Get(id))\n\tif meta == 0 {\n\t\treturn 0, fmt.Errorf(\"task does not exist or has expired\")\n\t}\n\treturn meta, nil\n}\n\n// worker loops forever, running queued tasks one at a time. Any returned errors are logged.\nfunc (t *tasks) worker() {\n\tshouldCleanup := time.Tick(time.Hour)\n\n\tfor {\n\t\t// If the server is shutting down, return immediately. Else, fetch a task from the queue.\n\t\tvar task taskRequest\n\t\tselect {","sourceCodeStart":182,"sourceCodeEnd":218,"githubUrl":"https://github.com/dgraph-io/dgraph/blob/759e242be62c91f8d084da06ad0c8d21256d9c07/worker/queue.go#L182-L218","documentation":"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.","triggerScenarios":"Calling get/TaskStatus with id == 0 (e.g. the ID from a failed Enqueue) or id == math.MaxUint64 (sentinel/reserved value passed by mistake).","commonSituations":"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.","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"],"exampleFix":"// before\nmeta, _ := tasks.get(id) // id may be 0\n// after\nif id == 0 || id == math.MaxUint64 {\n    return fmt.Errorf(\"no valid task ID; did Enqueue fail?\")\n}\nmeta, err := tasks.get(id)","handlingStrategy":"validation","validationCode":"func validID(id uint64) bool { return id != 0 && id != math.MaxUint64 }\nif !validID(id) { return fmt.Errorf(\"task ID %d is not a real task ID\", id) }","typeGuard":"func isRealTaskID(id uint64) bool {\n    return id != 0 && id != math.MaxUint64\n}","tryCatchPattern":"meta, err := tasks.Get(id)\nif err != nil && strings.Contains(err.Error(), \"task ID is invalid\") {\n    return fmt.Errorf(\"task ID %d invalid; only IDs from a successful Enqueue are queryable\", id)\n}","preventionTips":["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"],"tags":["validation","task-id","dgraph"],"backgroundTag":"invalid-task-id","analyzedSha":"759e242be62c91f8d084da06ad0c8d21256d9c07","analyzedAt":"2026-09-01T14:42:12.034Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}