facebook/relay · error
Expected field backing a Client Edge to be a Relay Resolver.
Error message
Expected field backing a Client Edge to be a Relay Resolver. {field:?} What it means
In the client edge build path for scalar-backed fields, the compiler looks up Relay Resolver metadata (@relay_resolver-style directives) on the scalar field backing a client edge. If the field is a ScalarField but carries no resolver metadata, the compiler cannot treat it as a client edge backing field and panics, printing the field.
Source
Thrown at compiler/crates/relay-codegen/src/build_ast.rs:2167
}
fn build_reader_client_edge(
&mut self,
context: &mut ContextualMetadata,
client_edge_metadata: &ClientEdgeMetadata<'_>,
required_metadata: Option<RequiredMetadataDirective>,
catch_metadata: Option<CatchMetadataDirective>,
) -> Primitive {
context.has_client_edges = true;
let backing_field = match &client_edge_metadata.backing_field {
Selection::FragmentSpread(fragment_spread) => {
self.build_fragment_spread(fragment_spread)
}
Selection::ScalarField(field) => {
if let Some(resolver_metadata) = RelayResolverMetadata::find(&field.directives) {
self.build_scalar_backed_resolver_field(context, field, resolver_metadata)
} else {
panic!("Expected field backing a Client Edge to be a Relay Resolver. {field:?}")
}
}
_ => panic!(
"Expected Client Edge backing field to be a Relay Resolver. {:?}",
client_edge_metadata.backing_field
),
};
let selections_item = if required_metadata.is_none() {
self.build_linked_field(context, client_edge_metadata.linked_field)
} else {
let next_directives = client_edge_metadata
.linked_field
.directives
.iter()
.filter(|directive| {
directive.name.item != RequiredMetadataDirective::directive_name()
})View on GitHub (pinned to 668b1b85e0)
Solutions
- Add the Relay Resolver directive (e.g. @relay_resolver with root_fragment_name) to the backing scalar field.
- If the field is not a resolver, change the client edge to point at the correct resolver-backed field.
- Check that no custom transform strips the resolver directives before codegen.
- Validate the client schema extension with the relay compiler's schema checks before compiling documents.
Example fix
// before
extend type Query { myEdge: MyType @clientEdge }
// after
extend type Query { myEdge: MyType @relay_resolver(root_fragment_name: "MyEdgeFragment") @clientEdge } Defensive patterns
Strategy: validation
Validate before calling
function validateResolverDirective(field) {
const hasResolver = field.directives?.some(d =>
['relay_resolver', 'relayResolver'].includes(d.name.value));
if (!hasResolver) {
throw new Error('Field ' + field.name.value + ' backs a client edge but has no @relay_resolver directive');
}
} Type guard
function isRelayResolverField(field) {
return field?.directives?.some(d => d.name.value === 'relay_resolver') === true;
} Try / catch
try {
compile();
} catch (e) {
if (String(e).includes('backing a Client Edge to be a Relay Resolver')) {
console.error('Add @relay_resolver to the backing field:', e.message);
} else throw e;
} Prevention
- Always annotate client edge backing scalars with @relay_resolver
- Grep schema extensions for client edges missing resolver directives before compiling
- Avoid custom transforms that strip resolver directives
- Validate client schema extensions in CI
When it happens
Trigger: A client edge whose backing scalar field lacks RelayResolverMetadata directives — e.g. the @relay_resolver directive was removed, renamed, or never added while the field is still wired as a client edge backing field.
Common situations: Removing a resolver directive during refactoring while leaving client edge wiring; schema extensions generated by older tooling without resolver annotations; directives stripped by an earlier transform.
Related errors
- Expected client edge backing field to be transformed into ex
- Expected Client Edge backing field to be a Relay Resolver. {
- unexpected value for @defer if argument: {other:?}
- unexpected value for @stream if argument: {other:?}
- Unexpected custom directives: {:#?}
AI-assisted analysis of facebook/relay@668b1b85e0 (2026-09-02).
Data as JSON: /api/errors/4d3cad297ea0d403.
Report an issue: GitHub.