{"record":{"id":"36ed251082369729","repo":"facebook/relay","slug":"expected-at-most-one-handle-directive-got-handl","errorCode":null,"errorMessage":"Expected at most one handle directive, got `{handle_field_directive:?}` and `{other_handle_field_directive:?}`.","messagePattern":"Expected at most one handle directive, got `(.+?)` and `(.+?)`\\.","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"compiler/crates/relay-codegen/src/build_ast.rs","lineNumber":1463,"sourceCode":"                    });\n                }\n            };\n            result.push(Primitive::Key(self.object(object)))\n        }\n    }\n\n    fn build_field_name_and_alias(\n        &self,\n        mut name: StringKey,\n        alias: Option<WithLocation<StringKey>>,\n        directives: &[Directive],\n    ) -> (StringKey, Option<StringKey>) {\n        let mut alias = alias.map(|alias| alias.item);\n        if self.variant == CodegenVariant::Reader {\n            let mut handle_field_directives = extract_handle_field_directives(directives);\n            if let Some(handle_field_directive) = handle_field_directives.next() {\n                if let Some(other_handle_field_directive) = handle_field_directives.next() {\n                    panic!(\n                        \"Expected at most one handle directive, got `{handle_field_directive:?}` and `{other_handle_field_directive:?}`.\"\n                    );\n                }\n                let values = extract_values_from_handle_field_directive(handle_field_directive);\n                alias = alias.or(Some(name));\n                name = if values.key == CODEGEN_CONSTANTS.default_handle_key {\n                    format!(\"__{}_{}\", name, values.handle).intern()\n                } else {\n                    format!(\"__{}_{}\", values.key, values.handle).intern()\n                }\n            }\n        }\n        (name, alias)\n    }\n\n    fn build_fragment_spread(&mut self, frag_spread: &FragmentSpread) -> Primitive {\n        if let Some(no_inline_metadata) =\n            NoInlineFragmentSpreadMetadata::find(&frag_spread.directives)","sourceCodeStart":1445,"sourceCodeEnd":1481,"githubUrl":"https://github.com/facebook/relay/blob/668b1b85e06261aa3b58dabfc51f8b5524a70955/compiler/crates/relay-codegen/src/build_ast.rs#L1445-L1481","documentation":"In Reader codegen, a field may carry at most one @handle (handleField) directive. build_field_name_and_alias collects handle directives with an iterator and panics if a second one exists, because codegen cannot merge multiple handle aliases into one reader field.","triggerScenarios":"A scalar or linked field in a fragment annotated with more than one @handle directive (e.g. `@handle(key: \"\") @handle(key: \"\")`) compiled with CodegenVariant::Reader.","commonSituations":"Adding a second @handle for a different connection handler and forgetting the compiler allows only one per field; merge conflicts that keep two @handle lines; copying examples with multiple handles onto a single field.","solutions":["Keep only one @handle directive on the field; delete the duplicate.","If you need multiple handles, split the field into aliased duplicates, one per @handle, e.g. `me @handle(key: \"\")` and `me2: me @handle(key: \"other\")`.","Check git history/merge conflicts for accidentally duplicated directive lines.","Verify with a schema/docs check that handlers like connection or @appendEdge only need a single handle per field."],"exampleFix":"// before\nviewer @handle(key: \"connection_viewer\") @handle(key: \"other_viewer\") { id }\n// after\nviewer @handle(key: \"connection_viewer\") { id }\n","handlingStrategy":"validation","validationCode":"fn field_has_single_handle(field: &Field) -> Result<(), String> {\n    let count = field.directives.iter().filter(|d| d.name.item.0 == \"handle\").count();\n    if count > 1 { Err(format!(\"field {} has {} @handle directives\", field.name.item.0, count)) }\n    else { Ok(()) }\n}\n","typeGuard":null,"tryCatchPattern":"let result = std::panic::catch_unwind(|| build_scalar_field(...));\nif result.is_err() { report(\"field has more than one @handle directive\"); }\n","preventionTips":["Allow only one @handle per field; use aliased duplicate fields for multiple handles.","Add a GraphQL lint rule rejecting multiple @handle directives on one field.","Check merge diffs for duplicated directive lines."],"tags":["graphql","handle","directive","codegen"],"backgroundTag":"duplicate-directive","analyzedSha":"668b1b85e06261aa3b58dabfc51f8b5524a70955","analyzedAt":"2026-09-02T19:57:20.783Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-10T02:17:09.455Z"}