hasura/graphql-engine · error · Error

lookahead of a number cannot be a 'NameStart': {0:?}

Error message

lookahead of a number cannot be a 'NameStart': {0:?}

What it means

Lexer error raised when the character immediately following a number token is a GraphQL 'NameStart' character (letter or underscore). GraphQL requires number tokens to be delimited, so '123abc' is ambiguous/illegal and rejected by parse_number's lookahead check.

Source

Thrown at v3/crates/graphql/lang-graphql/src/lexer/number.rs:30

    Int64(i64),
}

impl Display for NumberToken {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        match self {
            NumberToken::Float64(float) => float.fmt(f),
            NumberToken::Int64(i) => i.fmt(f),
        }
    }
}

#[derive(Error, Debug, PartialEq, Eq, Clone)]
pub enum Error {
    #[error("expected a digit, but found: {found:?}")]
    DigitExpected { found: Option<u8> },
    #[error("failed to parse a number: {error:?}")]
    LexicalError { error: lexical_core::Error },
    #[error("lookahead of a number cannot be a 'NameStart': {0:?}")]
    NameStart(u8),
}

pub fn parse_number(bytes: &[u8]) -> Result<(NumberToken, usize), Error> {
    let number_start = 0;
    let mut ix = 0;
    // Parse the optional negative sign
    if let Some(&b'-') = bytes.get(ix) {
        ix += 1;
    }
    // Count the number of integers present, until you hit a non-digit.
    // This helps to distinguish between integers and floats
    let integer_count = bytes[ix..]
        .iter()
        .take_while(|&&b| b.is_ascii_digit())
        .count();
    if integer_count == 0 {
        return Err(Error::DigitExpected {

View on GitHub (pinned to 724551b9ae)

Solutions

  1. Insert a space/operator between the number and the following identifier
  2. Use variables for numeric values instead of inline literals
  3. Fix the client-side query template producing the concatenated token

Example fix

# before
{ users(limit:10and...) }
# after
{ users(limit: 10, ...) }
Defensive patterns

Strategy: validation

Validate before calling

// Reject a digit immediately followed by a name char
if (/\d[_A-Za-z]/.test(queryText)) throw new Error('number glued to identifier');

Type guard

const hasGluedNumberToken = (q) => /\d[_A-Za-z]/.test(q);

Try / catch

// Catch, report the byte offset from the lexer error, and insert separators

Prevention

When it happens

Trigger: Query text like '123abc', '0x1F', or a number immediately followed by a name with no separator; missing whitespace/operator between a number and an identifier.

Common situations: Broken string interpolation joining a number to the next token; typos such as units attached to numbers ('10px'); minification bugs removing whitespace.

Related errors


AI-assisted analysis of hasura/graphql-engine@724551b9ae (2026-08-28). Data as JSON: /api/errors/8c0e9cb769ebc545. Report an issue: GitHub.