facebook/relay · error
Expected to have a fragment name.
Error message
Expected to have a fragment name.
What it means
The Relay compiler's spread transform builds client-edge resolver metadata and expects every resolver field's fragment_name (from @returnFragment / @rootFragment lowering) to be Some by the time RelayResolverMetadata runs. It calls .expect("Expected to have a fragment name.") on field_metadata.fragment_name, so a None panics. Per the surrounding code conventions this indicates a compiler invariant violation, not a user-authored GraphQL error.
Source
Thrown at compiler/crates/relay-transforms/src/relay_resolvers/spread_transform.rs:164
import_path: field_metadata.import_path,
import_name: field_metadata.import_name,
field_alias: field.alias().map(|field_alias| field_alias.item),
field_path: field_metadata.field_path,
field_id: field.definition().item,
field_arguments,
fragment_arguments: fragment_arguments.clone(),
live: field_metadata.live,
output_type_info: field_metadata.output_type_info.clone(),
fragment_data_injection_mode: field_metadata
.fragment_data_injection_mode
.as_ref()
.map(|injection_mode| {
(
self.program
.fragment(
field_metadata
.fragment_name
.expect("Expected to have a fragment name."),
)
.expect("Expect to have a fragment node.")
.name,
*injection_mode,
)
}),
type_confirmed: field_metadata.type_confirmed,
resolver_type: field_metadata.resolver_type,
return_fragment: field_metadata.return_fragment,
};
let mut new_directives: Vec<Directive> = vec![resolver_metadata.into()];
for directive in field.directives() {
if directive.name.item != RelayResolverFieldMetadata::directive_name() {
new_directives.push(directive.clone())
}
}View on GitHub (pinned to 668b1b85e0)
Solutions
- Ensure the full standard Relay transform pipeline (including the pass that populates fragment_name on resolver field metadata) runs before the spread transform.
- Check field_metadata construction in relay_resolvers for a path that creates FieldMetadata without fragment_name.
- Reproduce with a minimal fragment/operation and file a bug against relay compiler relay_resolvers.
- Pin/upgrade to a relay compiler version where the ordering bug is fixed.
Defensive patterns
Strategy: validation
Validate before calling
if field_metadata.fragment_name.is_none() {
panic!("resolver field `{}` reached spread transform without fragment_name; transform pipeline misconfigured", field_metadata.name);
} Type guard
fn has_fragment_name(m: &FieldMetadata) -> bool { m.fragment_name.is_some() } Try / catch
let Some(fragment_name) = field_metadata.fragment_name else {
return Err(Diagnostic::error("resolver metadata missing fragment_name"));
}; Prevention
- Run the standard Relay transform pipeline in the documented order.
- Add debug asserts for resolver metadata invariants between transforms.
- Pin relay compiler crate versions across your build.
When it happens
Trigger: A field with resolver metadata (client-edge / @returnFragment flow) reaches this transform without fragment_name populated; typically a RelayResolverMetadata transform running on a program where the earlier pass that assigns fragment names was skipped or ran in the wrong order.
Common situations: Custom compiler builds with a modified transform pipeline, running the spread transform out of order, or internal Relay compiler bugs after upgrading relay crates.
Related errors
- Expect to have a fragment node.
- shadow resolver with @returnFragment must declare a @rootFra
- useRefetchableFragmentNode: Unexpected action type
- commitMutation: Expected mutation operation
- commitMutation: Expected mutation operation
AI-assisted analysis of facebook/relay@668b1b85e0 (2026-09-02).
Data as JSON: /api/errors/49d68100c9f28ae9.
Report an issue: GitHub.