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
- Replace the raw newline/tab with the escape sequence \n or \t
- Use a block string ("""...""") for multiline text
- 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
- Escape newlines/tabs as \\n/\\t in normal strings
- Use block strings for multiline text
- Lint embedded query strings for control characters
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
- unknown escape sequence in string: {0:?}
- unexpected character in the document: {0:?}
- invalid string literal found: {0:?}
- invalid number literal found: {0:?}
- parsing failed: {0}
AI-assisted analysis of hasura/graphql-engine@724551b9ae (2026-08-28).
Data as JSON: /api/errors/19e2b6e4f09d06e5.
Report an issue: GitHub.