facebook/relay · error

Cannot parse schema utf8 from bytes: {}

Error message

Cannot parse schema utf8 from bytes: {}

What it means

After a glob match is read into bytes, load_schema converts it to UTF-8 via String::from_utf8. Non-UTF-8 content aborts with 'Cannot parse schema utf8 from bytes'. SDL schema files must be valid UTF-8 text, so binary or wrongly-encoded files are rejected here.

Source

Thrown at compiler/crates/graphql-ir-diff/src/lib.rs:812

}

pub fn load_schema(schema_paths: Vec<String>) -> Result<Arc<SDLSchema>> {
    // Collect (content, file_path) pairs for each schema file
    let schema_files: Vec<(String, String)> = schema_paths
        .clone()
        .into_iter()
        .map(|pattern| {
            // expand if path contains "*"
            let paths = glob::glob(&pattern)
                .map_err(|e| anyhow!("Invalid glob pattern '{}': {}", pattern, e))?;
            let file_entries: Result<Vec<(String, String)>> = paths
                .map(|entry| {
                    let file_path =
                        entry.map_err(|e| anyhow!("Failed to read glob entry: {}", e))?;
                    let file_path_str = file_path.to_string_lossy().to_string();
                    let schema_bytes = fs::read(file_path)?;
                    let content = String::from_utf8(schema_bytes)
                        .map_err(|e| anyhow!("Cannot parse schema utf8 from bytes: {}", e))?;
                    Ok((content, file_path_str))
                })
                .collect();
            file_entries
        })
        .collect::<Result<Vec<_>>>()?
        .into_iter()
        .flatten()
        .collect();

    if schema_files.is_empty() {
        return Err(anyhow!(
            "No schema loaded for paths: {}",
            schema_paths.join(",")
        ));
    }

    // Build a source map for DiagnosticPrinter

View on GitHub (pinned to 668b1b85e0)

Solutions

  1. Identify the offending file from the underlying from_utf8 error and re-save it as UTF-8.
  2. Convert encodings (e.g. iconv -f UTF-16 -t UTF-8) for legacy files.
  3. Exclude non-schema files from the glob (tighten to '*.graphql'/'*.sdl') so binaries never match.
  4. Strip or normalize a UTF-8 BOM if tooling downstream chokes on it.

Example fix

// shell
iconv -f UTF-16 -t UTF-8 schema.graphql > schema.utf8.graphql
// after
load_schema(vec!["schemas/schema.utf8.graphql".to_string()])?;
Defensive patterns

Strategy: validation

Validate before calling

fn is_utf8_file(path: &str) -> bool {
    std::fs::read(path).map(|b| std::str::from_utf8(&b).is_ok()).unwrap_or(false)
}
// pre-check all schema files
for f in schema_files { assert!(is_utf8_file(&f), "non-UTF-8 schema file: {f}"); }

Try / catch

let schema = load_schema(patterns).map_err(|e| {
    if e.to_string().contains("utf8") {
        anyhow!("schema files must be UTF-8; re-save the offending file: {e}")
    } else { e }
});

Prevention

When it happens

Trigger: Calling load_schema/compare where a file matched by the schema glob is binary (e.g. a compiled artifact), UTF-16/Latin-1 encoded, or corrupted — from_utf8 fails and is wrapped into this anyhow error.

Common situations: Editors saving .graphql files with BOM/UTF-16 by misconfiguration; build artifacts accidentally matching '*.graphql' globs; files downloaded or committed with wrong encoding.

Related errors


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