facebook/relay · error

Expected to have a typegen operation for `{normal_name}`

Error message

Expected to have a typegen operation for `{normal_name}`

What it means

expect_typegen unwraps the optional typegen operation and panics if it is None. Every artifact rendered as Operation or UpdatableQuery must have a typegen AST; a missing one indicates inconsistent operation grouping upstream.

Source

Thrown at compiler/crates/relay-compiler/src/build_project/generate_artifacts.rs:369

        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.
/// `Programs::operation(name)` does a linear search, so it's more efficient to
/// group in a batch.
fn group_operations(programs: &Programs) -> FnvHashMap<StringKey, OperationGroup<'_>> {
    let mut grouped_operations: FnvHashMap<StringKey, OperationGroup<'_>> = programs
        .normalization
        .operations
        .iter()
        .map(|normalization_operation| {
            (
                normalization_operation.name.item.0,
                OperationGroup {
                    normalization: Some(normalization_operation),

View on GitHub (pinned to 668b1b85e0)

Solutions

  1. Clean the __generated__ output and compiler caches, then rerun the compiler
  2. Verify the operation doesn't use directives/flags that disable typegen generation
  3. Isolate the named operation and file a Relay compiler bug with a minimal repro
Defensive patterns

Strategy: try-catch

Validate before calling

if (artifact.typegen == null) {
  throw new Error(`Operation ${artifact.normalization?.name ?? 'MISSING_ENTRY'} lacks a typegen AST`);
}

Type guard

fn has_typegen(a: &ArtifactContent) -> bool { a.typegen.is_some() }

Try / catch

try {
  renderArtifact(group);
} catch (panic) {
  if (/Expected to have a typegen operation/.test(String(panic))) {
    cleanAndRecompile();
  } else throw panic;
}

Prevention

When it happens

Trigger: ArtifactContent::Operation or ArtifactContent::UpdatableQuery rendering calls expect_typegen on a group where self.typegen is None; the panic message shows the normalization name (or MISSING_ENTRY).

Common situations: Compiler bug or stale/incomplete compiler state after a Relay version bump; operations affected by transforms that suppress typegen output.

Related errors


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