dgraph-io/dgraph · error

backupNum value should be equal or greater than zero

Error message

backupNum value should be equal or greater than zero

What it means

verifyRestoreInput validates restore parameters for both restore and restoreTenant admin mutations and rejects a negative backupNum. backupNum controls how many backups are restored (latest N); the library defines the valid domain as zero or greater. The error is wrapped as 'couldn't get input argument' via schema.GQLWrapf, so it surfaces during input extraction, before any restore work starts.

Source

Thrown at graphql/admin/restore.go:174

	inputByts, err := json.Marshal(inputArg)
	if err != nil {
		return nil, schema.GQLWrapf(err, "couldn't get input argument")
	}

	var input restoreTenantInput
	if err := json.Unmarshal(inputByts, &input); err != nil {
		return nil, schema.GQLWrapf(err, "couldn't get input argument")
	}
	if err := verifyRestoreInput(input.RestoreInput); err != nil {
		return nil, err
	}

	return &input, nil
}

func verifyRestoreInput(input restoreInput) error {
	if input.BackupNum < 0 {
		err := errors.Errorf("backupNum value should be equal or greater than zero")
		return schema.GQLWrapf(err, "couldn't get input argument")
	}
	return nil
}

View on GitHub (pinned to 759e242be6)

Solutions

  1. Set backupNum to 0 (or omit it) to restore all backups, or to a positive integer to restore the latest N.
  2. Clamp computed values before sending: if n < 0 { n = 0 }.
  3. Replace '-1 means all' conventions in your tooling with the API's 0-means-all semantics.
  4. Re-check arithmetic deriving backupNum from a backup count; guard against empty lists yielding negative results.

Example fix

// before
mutation { restore(input: { location: "s3://bucket", backupNum: -1 }) { response { message } } }
// after
mutation { restore(input: { location: "s3://bucket", backupNum: 0 }) { response { message } } }
Defensive patterns

Strategy: validation

Validate before calling

function assertBackupNum(n) {
  const v = Number(n);
  if (!Number.isInteger(v) || v < 0) throw new Error('backupNum must be an integer >= 0');
  return v;
}

Type guard

function isNonNegativeInt(v) { return Number.isInteger(v) && v >= 0; }

Try / catch

try {
  await gql(restoreMutation, { input: { ...input, backupNum: Math.max(0, input.backupNum ?? 0) } });
} catch (e) {
  if (String(e.message).includes('backupNum value should be equal or greater than zero')) {
    // clamp to 0 (restore all) or a positive count and retry
  }
}

Prevention

When it happens

Trigger: Calling restore or restoreTenant with backupNum explicitly set to a negative value, e.g. {"backupNum": -1}, typically when a variable or computed expression yields a negative count.

Common situations: Scripts computing backupNum as (latest - N) where latest is unknown/zero and underflow occurs, default sentinel values of -1 meaning 'all' that the API does not accept, or off-by-one arithmetic over backup lists.

Related errors


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