facebook/relay · error
Expected presence of edges field to have been previously val
Error message
Expected presence of edges field to have been previously validated.
What it means
When transforming a @connection field, the compiler constructs an edges selection by looking up the edges field on the connection type via schema.named_field(...) and expects it to exist, trusting that connection validation (e.g. validation_rules checking ConnectionInterface compliance) already verified the field. Panicking means a connection-like field lacking an edges field reached the transform anyway.
Source
Thrown at compiler/crates/relay-transforms/src/transform_connections.rs:155
) -> Vec<Selection> {
let is_stream_connection = connection_directive.name.item
== self.connection_constants.stream_connection_directive_name;
let schema = &self.program.schema;
let transformed_selections = self
.transform_selections(&connection_field.selections)
.replace_or_else(|| connection_field.selections.clone());
let ((edges_ix, edges_field), page_info_selection) = assert_connection_selections(
schema,
&transformed_selections,
self.connection_interface,
);
let connection_field_type = schema.field(connection_field.definition.item).type_.inner();
// Construct edges selection
let edges_schema_field_id = schema
.named_field(connection_field_type, self.connection_interface.edges)
.expect("Expected presence of edges field to have been previously validated.");
let edges_schema_field = schema.field(edges_schema_field_id);
let edges_field_name = edges_schema_field.name.item;
let edge_type = edges_schema_field.type_.inner();
let mut is_aliased_edges = false;
let mut transformed_edges_field = if let Some(alias) = edges_field.alias {
is_aliased_edges = true;
// The edges selection has to be generated as non-aliased field (since product
// code may be accessing the non-aliased response keys).
if alias.item != edges_field_name {
// If an alias is present, and it is different from the field name,
// we need to build a new edges_selection
LinkedField {
alias: None,
definition: WithLocation::generated(edges_schema_field_id),
arguments: Vec::new(),
directives: Vec::new(),
selections: Vec::new(),View on GitHub (pinned to 668b1b85e0)
Solutions
- Ensure the connection field's type defines an edges field returning an object with a node field.
- Check the ConnectionInterface config (edges/page_info field names) matches your schema's actual field names.
- Keep the connection validation transform in the pipeline before transform_connections.
- Fix the @connection directive placement — it must be on a field whose type is a valid connection.
Example fix
// before: type UserConnection { pageInfo: PageInfo! } (missing edges)
// after
type UserConnection {
edges: [UserEdge!]!
pageInfo: PageInfo!
} Defensive patterns
Strategy: validation
Validate before calling
if schema.named_field(conn_type, "edges").is_none() {
return Err(Diagnostic::error(format!("@connection type {:?} has no edges field", conn_type)));
} Type guard
fn is_valid_connection(schema: &Schema, t: Type, ci: &ConnectionInterface) -> bool {
schema.named_field(t.inner(), ci.edges).is_some()
} Try / catch
let Some(edges_id) = schema.named_field(connection_field_type, self.connection_interface.edges) else {
return Err(Diagnostic::error("connection field missing edges"));
}; Prevention
- Define edges + pageInfo on every connection type.
- Match ConnectionInterface config names to your schema.
- Keep validate_connections before transform_connections.
When it happens
Trigger: A field annotated with @connection whose type does not actually implement the connection interface with an edges field, while the preceding connection validation pass was skipped, misconfigured, or the transform order changed.
Common situations: Custom connection interface names (ConnectionInterface config) that don't match the schema; hand-written mock/extended schemas missing edges; running transform_connections without validate_connections in the pipeline.
Related errors
- Expected presence of page_info field to have been previously
- Expected field to be defined on concrete type
- commitMutation: Expected mutation operation
- commitMutation: Expected mutation operation
- commitMutation: Expected mutation to be of type request
AI-assisted analysis of facebook/relay@668b1b85e0 (2026-09-02).
Data as JSON: /api/errors/d25814073980659f.
Report an issue: GitHub.