hasura/graphql-engine · error · Error

string is unterminated

Error message

string is unterminated

What it means

String lexer error: a string literal was never terminated. Beyond a missing closing quote, ending a string inside a Unicode escape sequence or including a raw line break also triggers it, since GraphQL strings cannot span lines.

Source

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

use std::cmp::min;
use std::str::from_utf8_unchecked;
use thiserror::Error;

#[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.

View on GitHub (pinned to 724551b9ae)

Solutions

  1. Close the string literal, escaping any embedded quotes or newlines
  2. Pass multiline text as a variable instead of an inline literal
  3. Verify the request body is fully transmitted (not truncated)

Example fix

# before
query { songs(where: {title: {_eq: "hey}}) }
# after
query($t: String!) { songs(where: {title: {_eq: $t}}) }
Defensive patterns

Strategy: validation

Validate before calling

// Client-side parse catches unterminated strings before sending
import { parse } from 'graphql';
try { parse(queryText); } catch (e) { fixQuery(e); }

Type guard

const isTerminatedString = (s) => (s.match(/"/g) ?? []).length % 2 === 0;

Try / catch

// Catch the lexer error, use its offset to locate the string, close or escape it

Prevention

When it happens

Trigger: Forgetting the closing '"'; a literal newline pasted inside a quoted string; a truncated query that ends mid-string; an unterminated \u escape.

Common situations: Multiline text pasted into an inline string argument; client template bugs; network truncation mid-request.

Related errors


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