{"record":{"id":"fad6297eec04612e","repo":"hasura/graphql-engine","slug":"failed-to-parse-a-number-error","errorCode":null,"errorMessage":"failed to parse a number: {error:?}","messagePattern":"failed to parse a number: (.+?)","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"v3/crates/graphql/lang-graphql/src/lexer/number.rs","lineNumber":28,"sourceCode":"    Float64(f64),\n    // Int32(i32),\n    Int64(i64),\n}\n\nimpl Display for NumberToken {\n    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n        match self {\n            NumberToken::Float64(float) => float.fmt(f),\n            NumberToken::Int64(i) => i.fmt(f),\n        }\n    }\n}\n\n#[derive(Error, Debug, PartialEq, Eq, Clone)]\npub enum Error {\n    #[error(\"expected a digit, but found: {found:?}\")]\n    DigitExpected { found: Option<u8> },\n    #[error(\"failed to parse a number: {error:?}\")]\n    LexicalError { error: lexical_core::Error },\n    #[error(\"lookahead of a number cannot be a 'NameStart': {0:?}\")]\n    NameStart(u8),\n}\n\npub fn parse_number(bytes: &[u8]) -> Result<(NumberToken, usize), Error> {\n    let number_start = 0;\n    let mut ix = 0;\n    // Parse the optional negative sign\n    if let Some(&b'-') = bytes.get(ix) {\n        ix += 1;\n    }\n    // Count the number of integers present, until you hit a non-digit.\n    // This helps to distinguish between integers and floats\n    let integer_count = bytes[ix..]\n        .iter()\n        .take_while(|&&b| b.is_ascii_digit())\n        .count();","sourceCodeStart":10,"sourceCodeEnd":46,"githubUrl":"https://github.com/hasura/graphql-engine/blob/724551b9ae87845594ef0408cff0e50eb6c90dc5/v3/crates/graphql/lang-graphql/src/lexer/number.rs#L10-L46","documentation":"Lexer error: the bytes looked like a number but lexical_core could not parse them as a valid numeric value (the underlying lexical error is in {error}). This catches numeric syntax that survives character scanning but violates numeric grammar, such as overflow of the target type or malformed float syntax.","triggerScenarios":"Extremely large integer literals exceeding the representable range; malformed exponent notation like '1e+'; locale/format artifacts pasted into query text.","commonSituations":"Passing 64-bit IDs larger than the float/int literal limit as inline literals; copy-pasting numbers with exotic formatting.","solutions":["Pass the large value as a string variable and coerce server-side, or as a variable of the proper scalar type","Fix the malformed exponent/float syntax","Check the lexical error variant for overflow vs syntax"],"exampleFix":"# before\nquery { node(id: 9007199254740993) }\n# after\nquery($id: bigint!) { node(id: $id) }","handlingStrategy":"validation","validationCode":"// Bound inline integer literals to safe range or switch to variables\nif (Math.abs(value) > Number.MAX_SAFE_INTEGER) useVariable();","typeGuard":"const isSafeInlineNumber = (n) => Number.isFinite(n) && Math.abs(n) <= Number.MAX_SAFE_INTEGER;","tryCatchPattern":"// On lexical number errors, inspect the variant: overflow -> variable; syntax -> fix literal","preventionTips":["Send big IDs as string/bigint variables","Avoid pasted formatted numbers"],"tags":["graphql","lexer","number","parse-error"],"backgroundTag":"graphql-number-lex-error","analyzedSha":"724551b9ae87845594ef0408cff0e50eb6c90dc5","analyzedAt":"2026-08-28T07:32:55.105Z","schemaVersion":2},"datasetVersion":"2026-08-28T11:17:15.048Z"}