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

  1. Ensure the connection field's type defines an edges field returning an object with a node field.
  2. Check the ConnectionInterface config (edges/page_info field names) matches your schema's actual field names.
  3. Keep the connection validation transform in the pipeline before transform_connections.
  4. 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

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


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