dgraph-io/dgraph · error

task ID is missing

Error message

task ID is missing

What it means

resolveTask looks up a background task (e.g. a backup restore) by ID via the admin GraphQL API. After getTaskInput succeeds it still checks that input.Id is a non-empty string and returns 'task ID is missing' if it is empty. The error guards the downstream strconv.ParseUint call, which would otherwise produce a confusing parse error on "".

Source

Thrown at graphql/admin/task.go:34

	"github.com/dgraph-io/dgraph/v25/graphql/resolve"
	"github.com/dgraph-io/dgraph/v25/graphql/schema"
	"github.com/dgraph-io/dgraph/v25/protos/pb"
	"github.com/dgraph-io/dgraph/v25/worker"
)

type taskInput struct {
	Id string
}

func resolveTask(ctx context.Context, q schema.Query) *resolve.Resolved {
	// Get Task ID.
	input, err := getTaskInput(q)
	if err != nil {
		return resolve.EmptyResult(q, err)
	}
	if input.Id == "" {
		return resolve.EmptyResult(q, fmt.Errorf("task ID is missing"))
	}
	taskId, err := strconv.ParseUint(input.Id, 0, 64)
	if err != nil {
		err = errors.Wrapf(err, "invalid task ID: %s", input.Id)
		return resolve.EmptyResult(q, err)
	}

	// Get TaskMeta from network.
	req := &pb.TaskStatusRequest{TaskId: taskId}
	resp, err := worker.TaskStatusOverNetwork(context.Background(), req)
	if err != nil {
		return resolve.EmptyResult(q, err)
	}
	meta := worker.TaskMeta(resp.GetTaskMeta())
	return resolve.DataResult(
		q,
		map[string]interface{}{q.Name(): map[string]interface{}{
			"kind":        meta.Kind().String(),

View on GitHub (pinned to 759e242be6)

Solutions

  1. Supply a valid task ID: { task(input: { id: "1" }) { ... } }.
  2. Capture the task ID from the restore/backup mutation response before querying task status.
  3. Add client-side validation rejecting empty id values before issuing the query.
  4. If the id is dynamic, log/assert it is non-empty; fix whatever failed to populate it.
  5. Remember the ID must also parse as an unsigned integer — use the exact ID returned by the server.

Example fix

// before
query { task(input: { id: "" }) { status } }
// after
query { task(input: { id: "42" }) { status } }
Defensive patterns

Strategy: validation

Validate before calling

function assertTaskId(id) {
  if (typeof id !== 'string' || id.trim() === '') throw new Error('task ID is required and must be a non-empty numeric string');
  if (!/^\d+$/.test(id.trim())) throw new Error('task ID must parse as an unsigned integer');
  return id.trim();
}

Type guard

function isValidTaskId(v) { return typeof v === 'string' && /^\d+$/.test(v); }

Try / catch

try {
  const res = await gql(taskQuery, { input: { id: assertTaskId(taskId) } });
} catch (e) {
  if (String(e.message).includes('task ID is missing')) {
    // re-fetch the task id from the original restore/backup response, then retry
  }
}

Prevention

When it happens

Trigger: Querying task with an empty id: { task(input: { id: "" }) { ... } }, omitting the id field in the input object, or a client template that interpolates an undefined/empty task ID.

Common situations: Automation that captures a task ID from a restore response into a variable that was never set, retry logic re-running a task query before the mutation response was parsed, or frontend state losing the id between requests.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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