{"record":{"id":"61ea42c58ac88f67","repo":"dgraph-io/dgraph","slug":"invalid-untildate-q-v","errorCode":null,"errorMessage":"invalid untilDate %q: %v","messagePattern":"invalid untilDate %q: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"graphql/admin/list_backups.go","lineNumber":87,"sourceCode":"\t}\n\tif input.LastNDays > 0 && input.SinceDate != \"\" {\n\t\treturn filter, errors.Errorf(\"lastNDays and sinceDate are mutually exclusive\")\n\t}\n\tif input.LastNDays > 0 {\n\t\tsince := time.Now().UTC().AddDate(0, 0, -input.LastNDays).Truncate(24 * time.Hour)\n\t\tfilter.Since = &since\n\t}\n\tif input.SinceDate != \"\" {\n\t\tt, err := parseGraphQLDate(input.SinceDate)\n\t\tif err != nil {\n\t\t\treturn filter, errors.Errorf(\"invalid sinceDate %q: %v\", input.SinceDate, err)\n\t\t}\n\t\tfilter.Since = &t\n\t}\n\tif input.UntilDate != \"\" {\n\t\tt, err := parseGraphQLDate(input.UntilDate)\n\t\tif err != nil {\n\t\t\treturn filter, errors.Errorf(\"invalid untilDate %q: %v\", input.UntilDate, err)\n\t\t}\n\t\tvar end time.Time\n\t\tif strings.Contains(input.UntilDate, \"T\") {\n\t\t\t// RFC3339 datetime: user gave an exact timestamp, respect it.\n\t\t\tend = t\n\t\t} else {\n\t\t\t// Plain date (YYYY-MM-DD): extend to end of that calendar day.\n\t\t\tend = t.Add(24*time.Hour - time.Millisecond)\n\t\t}\n\t\tfilter.Until = &end\n\t}\n\treturn filter, nil\n}\n\n// needsFullManifest returns true when the full manifest.json must be read.\n// It is true when the caller explicitly sets fullManifest OR when the query\n// selection set includes \"groups\", so existing queries that request groups\n// continue to receive populated data without any input change.","sourceCodeStart":69,"sourceCodeEnd":105,"githubUrl":"https://github.com/dgraph-io/dgraph/blob/759e242be62c91f8d084da06ad0c8d21256d9c07/graphql/admin/list_backups.go#L69-L105","documentation":"This error is thrown by buildBackupDateFilter in the Dgraph admin GraphQL API when the untilDate argument passed to the listBackups query cannot be parsed into a valid date/time. parseGraphQLDate is strict: it accepts a plain date (YYYY-MM-DD), a full RFC3339 datetime containing 'T', or a Unix timestamp, and any other format fails. The original parse error is embedded so the developer can see exactly which format check failed.","triggerScenarios":"Calling the admin GraphQL listBackups mutation/query with untilDate set to a string that parseGraphQLDate rejects: e.g. '03/15/2024', '15-03-2024', 'yesterday', '2024/03/15', or a truncated datetime missing timezone like '2024-03-15T10:00'.","commonSituations":"Developers pass human-friendly dates or locale-formatted strings (US MM/DD/YYYY), omit the 'T'/timezone in RFC3339 timestamps, or pass values produced by non-Go date formatters with different separators. Frontends that format Date objects with toLocaleString are a frequent source.","solutions":["Reformat untilDate as RFC3339, e.g. '2024-03-15T10:00:00Z', or as a plain date '2024-03-15'.","If passing a timestamp, send a Unix timestamp (integer string) which parseGraphQLDate accepts.","Check the embedded %v error in the message to see exactly which parse stage failed and correct that specific part.","Validate the string client-side with time.Parse(time.RFC3339, s) or new Date(value) before sending.","If the input comes from a config or CLI flag, echo and fix the raw value; look for stray whitespace or quotes."],"exampleFix":"// before\n{ listBackups(input: { location: \"s3://bucket\", untilDate: \"03/15/2024\" }) }\n// after\n{ listBackups(input: { location: \"s3://bucket\", untilDate: \"2024-03-15\" }) }","handlingStrategy":"validation","validationCode":"const RFC3339 = /^\\d{4}-\\d{2}-\\d{2}(T\\d{2}:\\d{2}:\\d{2}(\\.\\d+)?(Z|[+-]\\d{2}:\\d{2}))?$/;\nfunction isValidUntilDate(s) {\n  if (!RFC3339.test(s)) return false;\n  return !isNaN(new Date(s).getTime());\n}\n// pass only if isValidUntilDate(untilDate)","typeGuard":"function isRFC3339OrDate(s) {\n  return typeof s === 'string' && (/^\\d{4}-\\d{2}-\\d{2}$/.test(s) || !isNaN(Date.parse(s)) && s.includes('T'));\n}","tryCatchPattern":"try {\n  await listBackups({ untilDate });\n} catch (e) {\n  if (String(e.message).includes('invalid untilDate')) {\n    // fall back to a plain YYYY-MM-DD or RFC3339 reformatted value and retry once\n  }\n}","preventionTips":["Always emit RFC3339 (with T and timezone) or plain YYYY-MM-DD for untilDate","Validate with time.Parse(time.RFC3339, s) or Date.parse before sending","Never pass locale-formatted dates (MM/DD/YYYY) from the UI","Trim whitespace and strip surrounding quotes from config-derived values","Document the accepted formats next to your admin tooling"],"tags":["graphql","date-parsing","input-validation","admin-api"],"backgroundTag":"invalid-date-format","analyzedSha":"759e242be62c91f8d084da06ad0c8d21256d9c07","analyzedAt":"2026-09-01T14:42:12.034Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}