{"record":{"id":"1094c84adb3b2fad","repo":"facebook/relay","slug":"expected-to-find-a-supported-argument-as-checked-b","errorCode":null,"errorMessage":"expected to find a supported argument as checked before","messagePattern":"expected to find a supported argument as checked before","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"compiler/crates/relay-transforms/src/match_/hash_supported_argument.rs","lineNumber":76,"sourceCode":"        if !self.has_match_supported_arg(field) {\n            return transformed_field;\n        }\n\n        let mut new_field = match transformed_field {\n            Transformed::Keep => Arc::new(field.clone()),\n            Transformed::Replace(Selection::LinkedField(linked_field)) => linked_field,\n            Transformed::Delete | Transformed::Replace(_) => {\n                panic!(\n                    \"unexpected transformed_field in HashSupportedArgumentTransform: {transformed_field:?}\"\n                )\n            }\n        };\n\n        let supported_arg = Arc::make_mut(&mut new_field)\n            .arguments\n            .iter_mut()\n            .find(|arg| arg.name.item == MATCH_CONSTANTS.supported_arg)\n            .expect(\"expected to find a supported argument as checked before\");\n\n        let mut input = String::new();\n        match &supported_arg.value.item {\n            Value::Constant(ConstantValue::List(items)) => {\n                for item in items {\n                    if let ConstantValue::String(name) = item {\n                        input.push('\\0');\n                        input.push_str(name.lookup());\n                    } else {\n                        panic!(\"expected all supported arguments to be strings, as verified above\");\n                    }\n                }\n            }\n            Value::Constant(ConstantValue::String(name)) => {\n                // Single item lists can be written without the list wrapper per GraphQL spec\n                input.push('\\0');\n                input.push_str(name.lookup());\n            }","sourceCodeStart":58,"sourceCodeEnd":94,"githubUrl":"https://github.com/facebook/relay/blob/668b1b85e06261aa3b58dabfc51f8b5524a70955/compiler/crates/relay-transforms/src/match_/hash_supported_argument.rs#L58-L94","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before (schema): field used with @match declares no supported argument\ntype Query { viewer: User }\n// after\ntype Query {\n  viewer(supportedLocales: [Language!]): User\n}","handlingStrategy":"validation","validationCode":"function fieldHasSupportedArg(schema, fieldName, argName) {\n  const f = schema.getType('Query')?.getFields?.()[fieldName.split('.').pop()];\n  return Boolean(f && f.args && f.args.some(a => a.name === argName));\n}\n// before compiling:\n// if (!fieldHasSupportedArg(schema, 'Query.viewer', 'supportedLocales')) throw ...","typeGuard":"function isMatchSupportedField(field, argName) {\n  return Boolean(\n    field.arguments?.some(a => a.name === argName) &&\n    field.schemaDefinition?.arguments?.named?.(argName)\n  );\n}","tryCatchPattern":"try {\n  program = applyMatchTransform(program);\n} catch (e) {\n  if (String(e.message).includes('supported argument as checked before')) {\n    logInvariantViolation('match transform ran without prior supported-arg insertion');\n  }\n  throw e;\n}","preventionTips":["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."],"tags":["relay-compiler","graphql","invariant","match-transform","panic"],"backgroundTag":"match-supported-argument-invariant","analyzedSha":"668b1b85e06261aa3b58dabfc51f8b5524a70955","analyzedAt":"2026-09-02T19:57:20.783Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-10T02:17:09.455Z"}