{"record":{"id":"166a7a8692e82940","repo":"dgraph-io/dgraph","slug":"backupnum-value-should-be-equal-or-greater-than-ze","errorCode":null,"errorMessage":"backupNum value should be equal or greater than zero","messagePattern":"backupNum value should be equal or greater than zero","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"graphql/admin/restore.go","lineNumber":174,"sourceCode":"\tinputByts, err := json.Marshal(inputArg)\n\tif err != nil {\n\t\treturn nil, schema.GQLWrapf(err, \"couldn't get input argument\")\n\t}\n\n\tvar input restoreTenantInput\n\tif err := json.Unmarshal(inputByts, &input); err != nil {\n\t\treturn nil, schema.GQLWrapf(err, \"couldn't get input argument\")\n\t}\n\tif err := verifyRestoreInput(input.RestoreInput); err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn &input, nil\n}\n\nfunc verifyRestoreInput(input restoreInput) error {\n\tif input.BackupNum < 0 {\n\t\terr := errors.Errorf(\"backupNum value should be equal or greater than zero\")\n\t\treturn schema.GQLWrapf(err, \"couldn't get input argument\")\n\t}\n\treturn nil\n}\n","sourceCodeStart":156,"sourceCodeEnd":179,"githubUrl":"https://github.com/dgraph-io/dgraph/blob/759e242be62c91f8d084da06ad0c8d21256d9c07/graphql/admin/restore.go#L156-L179","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Set backupNum to 0 (or omit it) to restore all backups, or to a positive integer to restore the latest N.","Clamp computed values before sending: if n < 0 { n = 0 }.","Replace '-1 means all' conventions in your tooling with the API's 0-means-all semantics.","Re-check arithmetic deriving backupNum from a backup count; guard against empty lists yielding negative results."],"exampleFix":"// before\nmutation { restore(input: { location: \"s3://bucket\", backupNum: -1 }) { response { message } } }\n// after\nmutation { restore(input: { location: \"s3://bucket\", backupNum: 0 }) { response { message } } }","handlingStrategy":"validation","validationCode":"function assertBackupNum(n) {\n  const v = Number(n);\n  if (!Number.isInteger(v) || v < 0) throw new Error('backupNum must be an integer >= 0');\n  return v;\n}","typeGuard":"function isNonNegativeInt(v) { return Number.isInteger(v) && v >= 0; }","tryCatchPattern":"try {\n  await gql(restoreMutation, { input: { ...input, backupNum: Math.max(0, input.backupNum ?? 0) } });\n} catch (e) {\n  if (String(e.message).includes('backupNum value should be equal or greater than zero')) {\n    // clamp to 0 (restore all) or a positive count and retry\n  }\n}","preventionTips":["Treat 0 / omitted as 'restore all'; never use -1 as a sentinel","Clamp computed values: backupNum = Math.max(0, latest - skip)","Guard subtraction against empty backup lists","Validate all restore inputs before sending (backupId, backupPath too)","Keep backupNum non-negative in config templates"],"tags":["graphql","restore","input-validation","backups"],"backgroundTag":"invalid-graphql-input","analyzedSha":"759e242be62c91f8d084da06ad0c8d21256d9c07","analyzedAt":"2026-09-01T14:42:12.034Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}