facebook/relay · error
Expected to have a reader operation for `{normal_name}`
Error message
Expected to have a reader operation for `{normal_name}` What it means
expect_reader unwraps the optional reader operation of an operation group and panics if it is None. An artifact typed as Operation or UpdatableQuery requires a reader AST; its absence means grouping produced an inconsistent entry.
Source
Thrown at compiler/crates/relay-compiler/src/build_project/generate_artifacts.rs:357
impl OperationGroup<'_> {
fn new() -> Self {
OperationGroup {
normalization: None,
operation_text: None,
reader: None,
typegen: None,
}
}
fn expect_reader(&self) -> Arc<OperationDefinition> {
let normal_name = self
.normalization
.map_or("MISSING_ENTRY", |n| n.name.item.0.lookup());
Arc::clone(
self.reader.unwrap_or_else(|| {
panic!("Expected to have a reader operation for `{normal_name}`")
}),
)
}
fn expect_typegen(&self) -> Arc<OperationDefinition> {
let normal_name = self
.normalization
.map_or("MISSING_ENTRY", |n| n.name.item.0.lookup());
Arc::clone(
self.typegen.unwrap_or_else(|| {
panic!("Expected to have a typegen operation for `{normal_name}`")
}),
)
}
}
/// Groups operations from the given programs by name for efficient access.View on GitHub (pinned to 668b1b85e0)
Solutions
- Clear generated files and recompile from scratch
- Check that @updatable and reader-affecting directives are used per current Relay docs
- Create a minimal repro and file a Relay compiler issue with the operation name from the panic message
Defensive patterns
Strategy: try-catch
Validate before calling
// Ensure a reader AST exists before rendering the artifact
if (artifact.reader == null) {
throw new Error(`Operation ${artifact.normalization?.name ?? 'MISSING_ENTRY'} lacks a reader AST`);
} Type guard
fn has_reader(a: &ArtifactContent) -> bool { a.reader.is_some() } Try / catch
try {
renderArtifact(group);
} catch (panic) {
if (/Expected to have a reader operation/.test(String(panic))) {
recompileFromCleanState();
} else throw panic;
} Prevention
- Recompile from a clean state after upgrades
- Avoid directives/flags that drop reader ASTs in production schemas
- Report reproducible panics with the operation name from the message
When it happens
Trigger: ArtifactContent::Operation or ArtifactContent::UpdatableQuery rendering calls expect_reader on a group where self.reader is None while a normalization AST exists (normal_name is used in the message, or MISSING_ENTRY if absent).
Common situations: Relay compiler bug after an upgrade, or an operation whose reader AST was dropped by an earlier transform (e.g. @updatable misconfiguration).
Related errors
- Unexpected DynamicImport
- Unexpected RelayResolver
- 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/e3ce0325e4ad01a8.
Report an issue: GitHub.