facebook/relay · error

Previous validation passes ensured this exists.

Error message

Previous validation passes ensured this exists.

What it means

In spread_transform's transformed_field, a resolver field's metadata carries a fragment_name, so the program must contain a fragment definition with that name. The expect asserts that previous validation passes guaranteed it exists; when lookup fails, the compiled program is missing a referenced fragment. This signals the fragment was deleted, renamed, or never defined while the resolver field still references it.

Source

Thrown at compiler/crates/relay-transforms/src/relay_resolvers/spread_transform.rs:130

    fn new(
        program: &'program Program,
        pipeline: ResolversPipeline,
        enable_shadow_resolvers: bool,
    ) -> Self {
        Self {
            program,
            pipeline,
            enable_shadow_resolvers,
            errors: Default::default(),
        }
    }

    fn transformed_field(&self, field: &impl IrField) -> Option<Selection> {
        RelayResolverFieldMetadata::find(field.directives()).map(|field_metadata| {
            let fragment_definition = field_metadata.fragment_name.map(|fragment_name| {
                self.program
                    .fragment(fragment_name)
                    .expect("Previous validation passes ensured this exists.")
            });

            let (fragment_arguments, field_arguments) =
                field.arguments().iter().cloned().partition(|arg| {
                    if let Some(fragment_definition) = fragment_definition {
                        fragment_definition
                            .variable_definitions
                            .named(VariableName(arg.name.item.0))
                            .is_some()
                    } else {
                        false
                    }
                });

            let resolver_metadata = RelayResolverMetadata {
                import_path: field_metadata.import_path,
                import_name: field_metadata.import_name,
                field_alias: field.alias().map(|field_alias| field_alias.item),

View on GitHub (pinned to 668b1b85e0)

Solutions

  1. Define the fragment named in the @relay_resolver's fragment_name argument, or update the directive to an existing fragment name.
  2. Include all files containing relay resolver fragments in the compiler's document list (check the include globs in relay.config).
  3. Clear incremental compiler state/caches and rebuild to drop stale program artifacts.
  4. Run schema/fragment name validation before the spread transform to catch dangling references with a better message.

Example fix

// before
@relay_resolver(import_path: "UserNameResolver", fragment_name: "UserNameResolverFragment") // fragment deleted
// after
fragment UserNameResolverFragment on User { name } // define the referenced fragment
Defensive patterns

Strategy: validation

Validate before calling

// Before running the spread transform, verify all resolver fragment references resolve:
for resolver_directive in all_relay_resolver_directives(&documents) {
    let name = resolver_directive.arg("fragment_name").to_string();
    assert!(program.fragment(name).is_some(), "fragment {} referenced by @relay_resolver not found in program", name);
}

Type guard

fn resolver_fragments_exist(program: &Program) -> bool {
    program.fragments().all(|f| {
        RelayResolverFieldMetadata::find_in(f.selections_directives())
            .and_then(|m| m.fragment_name)
            .map(|name| program.fragment(name).is_some())
            .unwrap_or(true)
    })
}

Try / catch

// Panics abort compilation; validate program completeness first:
if !resolver_fragments_exist(&program) {
    return Err(anyhow!("@relay_resolver references a fragment missing from the compiled program"));
}
let output = transformed_field(&field);

Prevention

When it happens

Trigger: transform_scalar_field or transform_linked_field processes a @relay_resolver field whose metadata fragment_name points to a fragment not present in self.program — e.g. the fragment was removed from the document but the resolver directive still references it, or the program passed to the transform excludes the file defining it.

Common situations: Deleting or renaming a fragment referenced by @relay_resolver(fragment_name: ...) without updating the resolver; compiler configured with a partial file list so the defining file isn't included; stale incremental cache after refactors.

Related errors


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