facebook/relay · error

Parse error: {:?}

Error message

Parse error: {:?}

What it means

format_graphql_source in prettier-format parses the GraphQL source with parse_document; on parse errors it formats the error list with {:?} into an anyhow error. It means the GraphQL source string (e.g. embedded in a JS template literal) is not syntactically valid GraphQL and cannot be formatted.

Source

Thrown at compiler/crates/prettier-format/src/lib.rs:29

//! and JavaScript files containing graphql template literals using
//! the Rust prettier-style printing utilities.

use common::SourceLocationKey;
use extract_graphql::JavaScriptSourceFeature;
use extract_graphql::extract;
use graphql_syntax::parse_document;
use graphql_text_printer::prettier_print_document;

/// Format a GraphQL source string using prettier-compatible formatting.
///
/// Parses the input as a GraphQL executable document and returns
/// the formatted output.
pub fn format_graphql_source(
    source: &str,
    source_location: SourceLocationKey,
) -> anyhow::Result<String> {
    let document = parse_document(source, source_location)
        .map_err(|errors| anyhow::anyhow!("Parse error: {:?}", errors))?;
    let leading_comments = extract_leading_comments(source);
    let formatted = prettier_print_document(&document);
    if leading_comments.is_empty() {
        Ok(formatted)
    } else {
        Ok(format!("{}\n{}", leading_comments, formatted))
    }
}

/// Extract comment and blank lines from the beginning of a GraphQL source.
///
/// Returns everything up to (and including) the last line of the leading
/// comment block. A "leading comment block" is a contiguous run of lines
/// starting from the top of the file where every line is either a comment
/// (starts with `#`) or blank/whitespace-only.
fn extract_leading_comments(source: &str) -> &str {
    let mut end = 0;
    for line in source.lines() {

View on GitHub (pinned to 668b1b85e0)

Solutions

  1. Decode the Debug-printed errors in the message; they identify the invalid token/span in the source.
  2. Fix the GraphQL syntax inside the template literal / source string.
  3. If the literal contains interpolation, confirm the extraction step handles it or skip formatting that literal.
  4. Report the file and location via the passed SourceLocationKey when surfacing the error so users can find the broken literal.

Example fix

// before
format_graphql_source("query { user { name }", loc)?; // unbalanced brace
// after
format_graphql_source("query { user { name } }", loc)?;
Defensive patterns

Strategy: try-catch

Validate before calling

// Validate embedded GraphQL before formatting (plugin-level guard)
fn is_parseable(source: &str, loc: SourceLocationKey) -> bool {
    parse_document(source, loc).is_ok()
}

Try / catch

match format_graphql_source(source, loc) {
    Ok(out) => out,
    Err(e) => {
        // skip unparseable literals instead of failing the whole JS file
        eprintln!("skipping unparseable graphql literal: {e}");
        source.to_string()
    }
}

Prevention

When it happens

Trigger: Calling format_graphql_source(source, source_location) — from format_js_file on Relay's graphql`` template contents, or in tests/main — where parse_document returns syntax errors: unbalanced braces, invalid selection syntax, truncated documents from bad extraction.

Common situations: Prettier plugin (format_js_file) formatting JS files whose graphql`` literals were mangled by earlier transforms; template literals with JS interpolation ${...} inside GraphQL text that the parser can't handle; truncated extraction from minified code.

Understand the failure class

Related errors


AI-assisted analysis of facebook/relay@668b1b85e0 (2026-09-02). Data as JSON: /api/errors/9e18120a16a2f753. Report an issue: GitHub.