facebook/relay · error

No schema loaded for paths: {}

Error message

No schema loaded for paths: {}

What it means

load_schema aggregates all files matched by all schema_paths patterns; if the resulting schema_files list is empty, no schema was loaded at all, so it errors with the original comma-joined paths. This guards downstream schema building from an empty, meaningless input.

Source

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

                .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
    let source_map: HashMap<SourceLocationKey, TextSource> = schema_files
        .iter()
        .map(|(content, file_path)| {
            let source_key = SourceLocationKey::standalone(file_path);
            let text_source = TextSource::from_whole_document(content.clone());
            (source_key, text_source)
        })
        .collect();

    // Convert to (content, SourceLocationKey) tuples for build_schema_with_extensions_parallel
    let schema_sdls: Vec<(String, SourceLocationKey)> = schema_files
        .into_iter()

View on GitHub (pinned to 668b1b85e0)

Solutions

  1. Verify each glob pattern actually matches files (ls schemas/**/*.graphql or test in a shell) and fix typos/extension mismatches.
  2. Run from the correct working directory or switch to repo-root-relative/absolute paths.
  3. Confirm the schema files exist in CI (add a step listing them before the diff job).
  4. Fail fast with a pre-check: call glob::glob and assert at least one match before invoking load_schema.

Example fix

// before
load_schema(vec!["wrong_dir/*.gsdl".to_string()])?; // matches nothing
// after
load_schema(vec!["schemas/**/*.graphql".to_string()])?;
Defensive patterns

Strategy: validation

Validate before calling

fn patterns_match_files(patterns: &[String]) -> bool {
    patterns.iter().any(|p| {
        glob::glob(p).map(|it| it.count() > 0).unwrap_or(false)
    })
}
assert!(patterns_match_files(&schema_paths), "no schema files matched: {}", schema_paths.join(","));

Try / catch

match load_schema(paths.clone()) {
    Ok(s) => s,
    Err(e) if e.to_string().starts_with("No schema loaded") => {
        anyhow::bail!("check schema_paths and cwd; matched nothing: {}", paths.join(","))
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Calling load_schema(vec![...]) or compare() with patterns that match zero files: wrong directory, wrong extension (e.g. '*.gsdl' instead of '*.graphql'), typo'd path, or running from a different working directory.

Common situations: CI checked out a partial repo missing the schema directory; relative paths resolved against an unexpected cwd; glob patterns using paths valid on one machine but not another (absolute paths, user dirs).

Related errors


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