hasura/graphql-engine · error · Error

invalid unicode escape sequence in string. {0:?}

Error message

invalid unicode escape sequence in string. {0:?}

What it means

Thrown when a \u escape in a GraphQL string is malformed: fewer than 4 hex digits follow \u, or the digits do not form a valid scalar value. The detailed reason is embedded in the message.

Source

Thrown at v3/crates/graphql/lang-graphql/src/lexer/string.rs:36

    /// An unknown character in a string literal was found
    ///
    /// This occurs when an invalid source character is found in a string
    /// literal, such as ASCII control characters.
    #[error("unexpected character in string: {0:?}")]
    UnknownCharacterInString(char),

    /// An unknown escape sequence in a string literal was found
    ///
    /// Only a limited set of escape sequences are supported, this is emitted
    /// when e.g. `"\l"` is parsed.
    #[error("unknown escape sequence in string: {0:?}")]
    UnknownEscapeSequence(String),

    /// An invalid unicode escape sequence in a string literal was found, and
    /// an error message is provided.
    ///
    /// This began with `"\u"` being parsed and then something going wrong.
    #[error("invalid unicode escape sequence in string. {0:?}")]
    InvalidUnicodeEscapeSequence(String),
}

pub struct Consumed {
    /// Number of line breaks consumed.
    pub line_breaks: usize,
    /// Number of characters consumed without hitting a further line break.
    pub chars_without_further_line_break: usize,
}

impl Consumed {
    fn no_line_break(chars: usize) -> Consumed {
        Consumed {
            line_breaks: 0,
            chars_without_further_line_break: chars,
        }
    }

View on GitHub (pinned to 724551b9ae)

Solutions

  1. Ensure exactly 4 hexadecimal digits follow \u
  2. Re-check generated escapes for truncation or non-hex characters
  3. Emit supplementary characters as a proper surrogate pair or use the literal character

Example fix

# before
{ greet(name: "\\u12") }
# after
{ greet(name: "\\u0012") }
Defensive patterns

Strategy: validation

Validate before calling

fn valid_unicode_escape(hex: &str) -> bool {
    hex.len() == 4 && hex.chars().all(|c| c.is_ascii_hexdigit())
        && u32::from_str_radix(hex, 16).map(|c| char::from_u32(c).is_some()).unwrap_or(false)
}

Try / catch

Match on InvalidString(InvalidUnicodeEscapeSequence(msg)) and report the inner message with the string's position.

Prevention

When it happens

Trigger: Parsing a string containing "\\u12" (truncated), "\\uZZZZ" (non-hex characters), or a surrogate code point that is invalid as a standalone scalar.

Common situations: Dynamically generating \u escapes with string formatting that drops digits, truncation of pasted queries, or emitting unpaired surrogates from JSON-to-GraphQL converters.

Related errors


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