facebook/relay · error

Expected Condition with static value to have been pruned or

Error message

Expected Condition with static value to have been pruned or inlined.

What it means

Relay's codegen builder converts an @include/@skip directive condition into a serialized Primitive for the generated AST. By this point in the pipeline, any Condition whose value is a compile-time constant must have already been pruned (directive statically false) or inlined into the selection (statically true) by earlier normalization passes. Hitting Constant means a condition with a static value survived into key building, which the compiler considers a bug in earlier passes or an unsupported directive placement.

Source

Thrown at compiler/crates/relay-codegen/src/build_ast.rs:2471

                        aliased_fragment
                    }
                } else {
                    primitive
                }
            }
        }
    }

    fn build_condition(
        &mut self,
        context: &mut ContextualMetadata,
        condition: &Condition,
    ) -> Primitive {
        let selections = self.build_selections(context, condition.selections.iter());
        Primitive::Key(self.object(object! {
            condition: Primitive::String(match &condition.value {
                ConditionValue::Variable(variable) => variable.name.item.0,
                ConditionValue::Constant(_) => panic!(
                    "Expected Condition with static value to have been pruned or inlined."
                ),
            }),
            kind: Primitive::String(CODEGEN_CONSTANTS.condition_value),
            passing_value: Primitive::Bool(condition.passing_value),
            selections: selections,
        }))
    }

    pub fn build_operation_variable_definitions(
        &mut self,
        variable_definitions: &[VariableDefinition],
    ) -> AstKey {
        let var_defs = variable_definitions
            .iter()
            .map(|def| {
                let default_value = if let Some(const_val) = &def.default_value {
                    self.build_constant_value(&const_val.item)

View on GitHub (pinned to 668b1b85e0)

Solutions

  1. Replace static @skip/@include arguments with a variable, e.g. `field @skip(if: $shouldSkip)`, and pass the variable at runtime
  2. Remove the statically-valued @skip/@include directive entirely and add/remove the field in the document (or use `@required`/fragment composition) as appropriate
  3. Update the Relay Compiler so constant conditions are pruned/inlined; if using a custom pass, ensure it runs normalization that simplifies constant conditions before codegen
  4. If it appears to be a compiler bug (variable was intended), file a reduced reproduction against relay compiler

Example fix

// before
query { user { name @skip(if: false) email @include(if: true) } }
// after
query($showEmail: Boolean!) { user { name email @include(if: $showEmail) } }
Defensive patterns

Strategy: validation

Validate before calling

// Before compiling, scan documents for static directive args:
function hasStaticSkipInclude(doc) {
  const bad = [];
  visit(doc, {
    Directive(node) {
      if ((node.name.value === 'skip' || node.name.value === 'include') &&
          node.arguments?.some(a => a.value.kind !== 'Variable')) {
        bad.push(node.name.value);
      }
    }
  });
  return bad.length === 0;
}
if (!hasStaticSkipInclude(queryDoc)) throw new Error('Use variables with @skip/@include');

Type guard

function isVariableCondition(value) {
  return typeof value === 'object' && value !== null && 'variableName' in value;
}

Try / catch

try {
  compiled = compile(queryText);
} catch (e) {
  if (String(e).includes('pruned or inlined')) {
    // rewrite static @skip/@include to variables and retry
  }
  throw e;
}

Prevention

When it happens

Trigger: Building the primitive for a @skip or @include directive whose `if:` argument is a literal (e.g. `@skip(if: true)` or `@skip(if: false)`) instead of a variable; a compiler pass that failed to prune/inline such conditions before build_primitive_for_key runs.

Common situations: Hand-written GraphQL documents using static @skip/@include arguments; older or patched compiler pipelines where pruning/normalization was skipped or a new pass inserted conditions without simplifying constants; test fixtures with literal directive args.

Related errors


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