{"record":{"id":"304de3789799b298","repo":"facebook/relay","slug":"failed-to-build-schema","errorCode":null,"errorMessage":"Failed to build schema:\n{}","messagePattern":"Failed to build schema:\n(.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"compiler/crates/graphql-ir-diff/src/lib.rs","lineNumber":859,"sourceCode":"    let schema_sdls: Vec<(String, SourceLocationKey)> = schema_files\n        .into_iter()\n        .map(|(content, file_path)| {\n            let source_key = SourceLocationKey::standalone(&file_path);\n            (content, source_key)\n        })\n        .collect();\n\n    let schema = schema::build_schema_with_extensions_parallel::<_, &str>(\n        &schema_sdls\n            .iter()\n            .map(|(content, key)| (content.as_str(), *key))\n            .collect::<Vec<_>>(),\n        &[],\n    )\n    .map_err(|diagnostics| {\n        let printer =\n            DiagnosticPrinter::new(|key: SourceLocationKey| source_map.get(&key).cloned());\n        anyhow!(\n            \"Failed to build schema:\\n{}\",\n            printer.diagnostics_to_string(&diagnostics)\n        )\n    })?;\n\n    Ok(Arc::new(schema))\n}\n\n/// Compare 2 GraphQL executable definitions belonging to the same schema, by subtracting doc2's normalized selection\n/// set from doc1's. Normalized selection set is the minimal set of (linked/scalar) field and argument combo that\n/// is selected by the executable, considering the field's type condition enforced by its {} enclosures. Comparison\n/// is assisted by typing information from the schema, passed as a comma separated list of paths.\n///\n/// # Returns (score, message)\n/// * `score` - numerical score in [0.0, 1.0], where 0 means doc1 is disjointed from doc2, and 1 means doc1 is\n///   a subset of doc2\n/// * `message` - details of relative complement of doc1 with respect to doc2, aka. doc1 - doc2\npub fn compare(schema_paths: Vec<String>, doc1: &str, doc2: &str) -> Result<(f64, String)> {","sourceCodeStart":841,"sourceCodeEnd":877,"githubUrl":"https://github.com/facebook/relay/blob/668b1b85e06261aa3b58dabfc51f8b5524a70955/compiler/crates/graphql-ir-diff/src/lib.rs#L841-L877","documentation":"After collecting schema file contents, load_schema builds an SDLSchema from the parsed sources. If schema building produces GraphQL diagnostics (duplicate type definitions, invalid SDL, unknown directives/types, syntax errors in SDL files), they are printed via DiagnosticPrinter and wrapped as 'Failed to build schema'. The individual files parsed as text but the combined type-system is invalid.","triggerScenarios":"Calling load_schema/compare where the union of matched SDL files fails schema validation — e.g. two globs match overlapping files causing duplicate type definitions, or a schema file contains invalid SDL.","commonSituations":"Glob patterns ('schemas/*.graphql', 'schemas/**/*.graphql') matching the same file twice; merging generated and hand-written schema files that redefine types; a schema file edited with invalid SDL.","solutions":["Read the printed diagnostics under 'Failed to build schema:' — they name the offending definitions and locations.","Fix invalid SDL in the reported schema file (syntax, unknown types/directives).","De-duplicate matched files: make glob patterns disjoint (don't combine '*.graphql' and '**/*.graphql' over the same tree).","Split schema content so each type/directive is defined exactly once across all matched files."],"exampleFix":"// before\nload_schema(vec![\"schemas/*.graphql\".into(), \"schemas/**/*.graphql\".into()])?; // dup files -> duplicate types\n// after\nload_schema(vec![\"schemas/**/*.graphql\".into()])?;","handlingStrategy":"try-catch","validationCode":"// Detect overlapping globs that would double-load the same file\nfn has_duplicate_matches(patterns: &[String]) -> bool {\n    let mut seen = std::collections::HashSet::new();\n    patterns.iter().any(|p| {\n        glob::glob(p).unwrap().filter_map(Result::ok).any(|path| !seen.insert(path))\n    })\n}\nassert!(!has_duplicate_matches(&schema_paths));","typeGuard":null,"tryCatchPattern":"let schema = load_schema(paths.clone()).map_err(|e| {\n    if e.to_string().starts_with(\"Failed to build schema\") {\n        eprintln!(\"{e}\"); // includes DiagnosticPrinter output with file locations\n        anyhow!(\"fix SDL per diagnostics above\")\n    } else { e }\n});","preventionTips":["Keep glob patterns disjoint so no file is included twice.","Validate combined SDL (e.g. via build_schema in tests) on every schema change.","Define each type/directive in exactly one file."],"tags":["graphql","sdl","schema-validation","diagnostics"],"backgroundTag":"schema-validation-failed","analyzedSha":"668b1b85e06261aa3b58dabfc51f8b5524a70955","analyzedAt":"2026-09-02T19:57:20.783Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-10T02:17:09.455Z"}