hasura/graphql-engine · error · Error

expected a digit, but found: {found:?}

Error message

expected a digit, but found: {found:?}

What it means

Lexer error: while scanning a number literal the parser expected a digit at the current position but found something else (found: Option<u8>, None means end of input). Produced by parse_number when the numeric token is malformed.

Source

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

pub enum NumberToken {
    // Float32(f32),
    Float64(f64),
    // Int32(i32),
    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()

View on GitHub (pinned to 724551b9ae)

Solutions

  1. Fix the number literal in the query (ensure integer and fractional parts are present)
  2. Send numeric values as GraphQL variables instead of inline literals
  3. Log the raw query text at the point of failure to spot truncation

Example fix

# before
query { songs(where: {duration: {_gt: .5}}) }
# after
query($d: Int!) { songs(where: {duration: {_gt: $d}}) }
Defensive patterns

Strategy: validation

Validate before calling

// Lint numeric literals in the query before sending
const BAD = /(?<![\w.])(\.\d*|\d+\.)(?![\d])/;

Type guard

const looksLikeCompleteNumber = (tok) => /^-?(\d+|\d+\.\d+|\d+[eE][+-]?\d+)$/.test(tok);

Try / catch

// Catch lex errors client-side, log the offending offset, and fix the literal

Prevention

When it happens

Trigger: Query text containing malformed numbers like '1.', '.e5', or a bare '-' where the integer part is missing; truncated queries cut off mid-number.

Common situations: Interpolating values into query strings with broken formatting; minified/truncated query payloads; template bugs dropping digits.

Related errors


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