hasura/graphql-engine · error · Error

unexpected character in string: {0:?}

Error message

unexpected character in string: {0:?}

What it means

Thrown by the GraphQL lexer's string scanner when it encounters a character that is not allowed inside a GraphQL string literal. GraphQL strings may only contain printable characters plus supported escapes; raw ASCII control characters (e.g. a literal newline or tab inside a normal string) trigger this. The offending character is included in the message.

Source

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

#[derive(Error, Debug, PartialEq, Eq, Clone)]
pub enum Error {
    #[error("expected a \" but found: {0:?}")]
    StartingSequenceNotFound(Option<u8>),

    /// An unterminated string literal was found
    ///
    /// Apart from forgetting the ending `"`, terminating a string within a
    /// Unicode escape sequence or having a line break in the string also
    /// causes this error.
    #[error("string is unterminated")]
    Unterminated,

    /// 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 {

View on GitHub (pinned to 724551b9ae)

Solutions

  1. Replace the raw newline/tab with the escape sequence \n or \t
  2. Use a block string ("""...""") for multiline text
  3. Sanitize/inspect input for control characters before parsing

Example fix

// before
let q = "{ set(name: \"line1
line2\") }"; // raw newline inside string
// after
let q = "{ set(name: \"line1\\nline2\") }"; // escaped newline
Defensive patterns

Strategy: validation

Validate before calling

fn has_raw_control_chars(s: &str) -> bool {
    s.chars().any(|c| (c.is_control() && c != '\t') || c == '\n' || c == '\r')
}
assert!(!has_raw_control_chars(query));

Try / catch

match graphql_lexer::Lexer::new(src).next() { Some(Err(e)) => /* report e with position */ , _ => {} }

Prevention

When it happens

Trigger: Scanning a query or SDL document containing a normal (non-block) string with an embedded raw control character, e.g. "a\nb" written with a real newline instead of \n, or a pasted string with a hidden control char.

Common situations: Multiline query text embedded in source code without triple-quote block strings, copy-pasted queries with invisible characters, or queries built via string concatenation across lines.

Related errors


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