facebook/relay · error

@__metadata directive should have only one argument!

Error message

@__metadata directive should have only one argument!

What it means

When building codegen AST metadata, the @__metadata directive must carry exactly one argument. build_internal_metadata_directives panics if directive.arguments.len() != 1, since internal metadata is encoded as a single key/value entry.

Source

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

            definition_source_location,
        }
    }

    fn object(&mut self, object: Vec<ObjectEntry>) -> AstKey {
        self.ast_builder.intern(Ast::Object(object))
    }

    fn array(&mut self, array: Vec<Primitive>) -> AstKey {
        self.ast_builder.intern(Ast::Array(array))
    }

    fn build_internal_metadata_directives(&mut self, directives: &[Directive]) -> Vec<ObjectEntry> {
        directives
            .iter()
            .filter_map(|directive| {
                if directive.name.item == *INTERNAL_METADATA_DIRECTIVE {
                    if directive.arguments.len() != 1 {
                        panic!("@__metadata directive should have only one argument!");
                    }

                    let arg = &directive.arguments[0];
                    let key = arg.name.item;
                    let value = match &arg.value.item {
                        Value::Constant(value) => self.build_constant_value(value),
                        _ => {
                            panic!("@__metadata directive expect only constant argument values.");
                        }
                    };

                    Some(ObjectEntry { key: key.0, value })
                } else {
                    None
                }
            })
            .collect()
    }

View on GitHub (pinned to 668b1b85e0)

Solutions

  1. Edit the document so @__metadata has exactly one argument, e.g. @__metadata(parentType: "Query").
  2. Regenerate the file with the same relay compiler version that consumes it instead of hand-editing generated code.
  3. If you manage multiple compiler versions, align the version producing @__metadata with the version parsing it.
  4. Remove stray @__metadata directives that were accidentally left in hand-written fragments.

Example fix

// before
fragment FooResolver on Query @__metadata(a: "x", b: "y") { ... }
// after
fragment FooResolver on Query @__metadata(parentType: "Query") { ... }
Defensive patterns

Strategy: validation

Validate before calling

fn validate_metadata_directive(d: &Directive) -> Result<(), String> {
    if d.name.item.0 == "__metadata" && d.arguments.len() != 1 {
        return Err("@__metadata must have exactly one argument".into());
    }
    Ok(())
}

Try / catch

let result = std::panic::catch_unwind(|| build_fragment_metadata(...));
if result.is_err() { report("invalid @__metadata directive shape"); }

Prevention

When it happens

Trigger: A GraphQL document contains `@__metadata` with zero or multiple arguments, encountered while building fragment metadata (build_fragment_metadata) or request parameters (build_request_parameters).

Common situations: Hand-editing a fragment with @__metadata and dropping or adding arguments; an older/newer compiler version emitting a different @__metadata shape than the consumer expects; a code generator writing malformed metadata directives.

Related errors


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