dgraph-io/dgraph · error
invalid task ID: %#x
Error message
invalid task ID: %#x
What it means
TaskStatusOverNetwork validates the task ID from a TaskStatusRequest before decoding it; an ID of 0 cannot encode a Raft ID in its upper 32 bits (taskId >> 32), so it is rejected with 'invalid task ID: %#x'. This is an input-validation error indicating the client passed an uninitialized or malformed task ID.
Source
Thrown at worker/queue.go:35
"github.com/golang/glog"
"github.com/pkg/errors"
"github.com/dgraph-io/dgraph/v25/conn"
"github.com/dgraph-io/dgraph/v25/protos/pb"
"github.com/dgraph-io/dgraph/v25/raftwal"
"github.com/dgraph-io/dgraph/v25/x"
"github.com/dgraph-io/ristretto/v2/z"
)
// TaskStatusOverNetwork fetches the status of a task over the network. Alphas only know about the
// tasks created by them, but this function would fetch the task from the correct Alpha.
func TaskStatusOverNetwork(ctx context.Context, req *pb.TaskStatusRequest,
) (*pb.TaskStatusResponse, error) {
// Extract Raft ID from Task ID.
taskId := req.GetTaskId()
if taskId == 0 {
return nil, fmt.Errorf("invalid task ID: %#x", taskId)
}
raftId := taskId >> 32
// Skip the network call if the required Alpha is me.
myRaftId := State.WALstore.Uint(raftwal.RaftId)
if raftId == myRaftId {
worker := (*grpcWorker)(nil)
return worker.TaskStatus(ctx, req)
}
// Find the Alpha with the required Raft ID.
var addr string
for _, group := range groups().state.GetGroups() {
for _, member := range group.GetMembers() {
if member.GetId() == raftId {
addr = member.GetAddr()
}
}View on GitHub (pinned to 759e242be6)
Solutions
- Check the error returned by Enqueue/initial mutation before using the returned task ID (error and ID can both be zero)
- Only build a TaskStatusRequest with a nonzero task ID obtained from a successful Enqueue
- If the original task ID was lost, re-run the backup/export operation to get a new one
Example fix
// before
resp, _ := pb.TaskStatusOverNetwork(ctx, &pb.TaskStatusRequest{TaskId: id})
// after
if id == 0 {
return fmt.Errorf("no task ID recorded from mutation")
}
resp, err := pb.TaskStatusOverNetwork(ctx, &pb.TaskStatusRequest{TaskId: id})
if err != nil { return err } Defensive patterns
Strategy: validation
Validate before calling
func validTaskID(id uint64) bool { return id != 0 }
// call: if !validTaskID(req.GetTaskId()) { return error } Type guard
func hasTaskID(req *pb.TaskStatusRequest) bool {
return req != nil && req.GetTaskId() != 0
} Try / catch
meta, err := worker.TaskStatusOverNetwork(ctx, req)
if err != nil && strings.Contains(err.Error(), "invalid task ID") {
return fmt.Errorf("no task ID recorded; capture the ID returned by a successful enqueue")
} Prevention
- Never ignore the error return of Enqueue — the ID is only valid on success
- Persist the task ID immediately after receiving it
- Initialize protobuf fields explicitly rather than relying on zero values
When it happens
Trigger: Calling TaskStatusOverNetwork (e.g. via the resolveTask path, often while retrying a mutation that returned a task ID) with req.GetTaskId() == 0 — typically when the original mutation response was never populated with a task ID.
Common situations: A client stores the task ID before the mutation RPC returns and the field defaults to zero; retry logic constructs a TaskStatusRequest from an empty protobuf; code that ignores the error from Enqueue and uses the 0 ID returned alongside it.
Related errors
- task ID is invalid: %d
- 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/4f67101a66abae52.
Report an issue: GitHub.