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
- Edit the document so @__metadata has exactly one argument, e.g. @__metadata(parentType: "Query").
- Regenerate the file with the same relay compiler version that consumes it instead of hand-editing generated code.
- If you manage multiple compiler versions, align the version producing @__metadata with the version parsing it.
- 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
- Never hand-edit @__metadata directives; regenerate them with the compiler.
- Validate all @__metadata directives have exactly one argument in a lint pass.
- Pin one relay compiler version for both emitting and consuming metadata.
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
- @__metadata directive expect only constant argument values.
- unknown @catch `to` value. Use `NULL` or `RESULT` (default)
- Duplicate fragment definitions named {}: first one: {:?} s
- The {} argument in exec_time_resolvers directive should be t
- Expected at most one handle directive, got `{handle_field_di
AI-assisted analysis of facebook/relay@668b1b85e0 (2026-09-02).
Data as JSON: /api/errors/239b42284c518b75.
Report an issue: GitHub.