facebook/relay · error
Unexpected RelayResolver
Error message
Unexpected RelayResolver
What it means
Internal invariant panic in write_constant_value: a Primitive::RelayResolverModel (a resolver reference) was passed where only printable constant primitives are allowed. Resolver references must be handled by dedicated printer paths, not constant printing.
Source
Thrown at compiler/crates/relay-codegen/src/printer.rs:937
f.pop();
}
f.push('}');
Ok(())
}
}
}
Primitive::Null | Primitive::SkippableNull => {
f.push_str("null");
Ok(())
}
Primitive::StorageKey(_, _) => panic!("Unexpected StorageKey"),
Primitive::RawString(_) => panic!("Unexpected RawString"),
Primitive::GraphQLModuleDependency(_) => panic!("Unexpected GraphQLModuleDependency"),
Primitive::JSModuleDependency { .. } => panic!("Unexpected JSModuleDependency"),
Primitive::ResolverModuleReference { .. } => panic!("Unexpected ResolverModuleReference"),
Primitive::PropertyAccessor(_) => panic!("Unexpected PropertyAccessor"),
Primitive::DynamicImport { .. } => panic!("Unexpected DynamicImport"),
Primitive::RelayResolverModel { .. } => panic!("Unexpected RelayResolver"),
}
}
View on GitHub (pinned to 668b1b85e0)
Solutions
- Ensure resolvers are referenced only from fields/exports, not as literal constant values
- Check resolver @exportable/@RelayResolver usage so model references are routed through export paths
- File a Relay compiler bug with a minimal repro — this branch should be unreachable in valid schemas
Defensive patterns
Strategy: validation
Validate before calling
// Resolve RelayResolverModel references to their export/field value before printing
let resolved = match primitive {
Primitive::RelayResolverModel { .. } => resolve_resolver_reference(primitive)?,
other => other,
};
write_constant_value(&resolved); Type guard
fn is_literal_primitive(p: &Primitive) -> bool {
!matches!(p, Primitive::RelayResolverModel { .. })
} Try / catch
// pre-validate; a panic here is a compiler bug, capture with a repro and report upstream
Prevention
- Keep resolver references out of constant/argument positions in the schema
- Resolve model references before the print phase
- Cover the printer with tests for every Primitive variant
When it happens
Trigger: write_argument_value or write_constant_value receives Primitive::RelayResolverModel — a Relay resolver model value reaching the constant/argument printing branch.
Common situations: A resolver whose return/argument type is another resolver, or a mis-wired resolver schema, causing the codegen printer to treat the resolver reference as a literal.
Related errors
- Unexpected DynamicImport
- Expected to have a reader operation for `{normal_name}`
- Expected at least one of an @updatable reader AST, or normal
- Expected to have a typegen operation for `{normal_name}`
- Expected a key
AI-assisted analysis of facebook/relay@668b1b85e0 (2026-09-02).
Data as JSON: /api/errors/2a28cfe727698a1e.
Report an issue: GitHub.