facebook/relay · error
expected to find a supported argument as checked before
Error message
expected to find a supported argument as checked before
What it means
transform_linked_field in the @match transform assumes the field it is rewriting was already confirmed (via has_match_supported_arg) to carry the 'supported' argument, so it force-unwraps the lookup of MATCH_CONSTANTS.supported_arg. The expect fires when that argument is missing at this point — an invariant violation meaning the pre-check and the argument rewrite are out of sync.
Source
Thrown at compiler/crates/relay-transforms/src/match_/hash_supported_argument.rs:76
if !self.has_match_supported_arg(field) {
return transformed_field;
}
let mut new_field = match transformed_field {
Transformed::Keep => Arc::new(field.clone()),
Transformed::Replace(Selection::LinkedField(linked_field)) => linked_field,
Transformed::Delete | Transformed::Replace(_) => {
panic!(
"unexpected transformed_field in HashSupportedArgumentTransform: {transformed_field:?}"
)
}
};
let supported_arg = Arc::make_mut(&mut new_field)
.arguments
.iter_mut()
.find(|arg| arg.name.item == MATCH_CONSTANTS.supported_arg)
.expect("expected to find a supported argument as checked before");
let mut input = String::new();
match &supported_arg.value.item {
Value::Constant(ConstantValue::List(items)) => {
for item in items {
if let ConstantValue::String(name) = item {
input.push('\0');
input.push_str(name.lookup());
} else {
panic!("expected all supported arguments to be strings, as verified above");
}
}
}
Value::Constant(ConstantValue::String(name)) => {
// Single item lists can be written without the list wrapper per GraphQL spec
input.push('\0');
input.push_str(name.lookup());
}View on GitHub (pinned to 668b1b85e0)
Solutions
- Verify has_match_supported_arg returned true for this exact field and that both checks see the same field definition.
- Run transforms in the documented order so the supported argument exists before transform_linked_field executes.
- Make sure the field's arguments are mutated in place on the same Field that gets compiled, not lost through cloning a stale structure.
- Confirm MATCH_CONSTANTS.supported_arg matches the argument name actually declared in your schema.
- Reproduce with a minimal @match fragment and file an issue with the compiler version if the invariant still breaks.
Example fix
// before (schema): field used with @match declares no supported argument
type Query { viewer: User }
// after
type Query {
viewer(supportedLocales: [Language!]): User
} Defensive patterns
Strategy: validation
Validate before calling
function fieldHasSupportedArg(schema, fieldName, argName) {
const f = schema.getType('Query')?.getFields?.()[fieldName.split('.').pop()];
return Boolean(f && f.args && f.args.some(a => a.name === argName));
}
// before compiling:
// if (!fieldHasSupportedArg(schema, 'Query.viewer', 'supportedLocales')) throw ... Type guard
function isMatchSupportedField(field, argName) {
return Boolean(
field.arguments?.some(a => a.name === argName) &&
field.schemaDefinition?.arguments?.named?.(argName)
);
} Try / catch
try {
program = applyMatchTransform(program);
} catch (e) {
if (String(e.message).includes('supported argument as checked before')) {
logInvariantViolation('match transform ran without prior supported-arg insertion');
}
throw e;
} Prevention
- Declare the supported argument on every field used with @match.
- Run compiler transforms in the documented order.
- Avoid mixing relay-transforms crate versions in a custom pipeline.
- Mutate Field structures in place; avoid cloning stale copies mid-pipeline so prior steps' effects persist.
When it happens
Trigger: A linked field is transformed for @match but its arguments contain no argument named MATCH_CONSTANTS.supported_arg — e.g. the supported-argument insertion step was skipped, ran on a different copy of the field, or the Arc::make_mut mutation landed on a stale clone.
Common situations: Custom compiler pipelines chaining match_ transforms out of order; transforms operating on cloned Program/Field structures so mutations never reach the compiled field; mixing relay-transforms crate versions where the supported_arg name changed.
Related errors
- Expected filters_arg to have been previously validated.
- field has supported arg, but missing from the schema
- Cannot have @module selections at multiple paths unless the
- Expect the module import inline fragment to have a type
- unexpected value for @defer if argument: {other:?}
AI-assisted analysis of facebook/relay@668b1b85e0 (2026-09-02).
Data as JSON: /api/errors/1094c84adb3b2fad.
Report an issue: GitHub.