{"record":{"id":"ea9ec964a50f0b2b","repo":"facebook/relay","slug":"expected-directive-to-have-a-path-argument","errorCode":null,"errorMessage":"Expected @{} directive to have a path argument","messagePattern":"Expected @(.+?) directive to have a path argument","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"compiler/crates/relay-typegen/src/visit.rs","lineNumber":2297,"sourceCode":"    }\n}\n\nfn transform_graphql_scalar_type(\n    typegen_context: &'_ TypegenContext<'_>,\n    scalar: ScalarID,\n    custom_scalars: &mut CustomScalarsImports,\n) -> AST {\n    let scalar_definition = typegen_context.schema.scalar(scalar);\n    let scalar_name = scalar_definition.name;\n    if let Some(directive) = scalar_definition\n        .directives\n        .named(DirectiveName(*CUSTOM_SCALAR_DIRECTIVE_NAME))\n    {\n        let path = directive\n            .arguments\n            .named(ArgumentName(*PATH_CUSTOM_SCALAR_ARGUMENT_NAME))\n            .unwrap_or_else(|| {\n                panic!(\n                    \"Expected @{} directive to have a path argument\",\n                    *CUSTOM_SCALAR_DIRECTIVE_NAME\n                )\n            })\n            .expect_string_literal();\n\n        let import_path = typegen_context.project_config.js_module_import_identifier(\n            &typegen_context\n                .project_config\n                .artifact_path_for_definition(typegen_context.definition_source_location),\n            &PathBuf::from(path.lookup()),\n        );\n\n        let export_name = directive\n            .arguments\n            .named(ArgumentName(*EXPORT_NAME_CUSTOM_SCALAR_ARGUMENT_NAME))\n            .unwrap_or_else(|| {\n                panic!(","sourceCodeStart":2279,"sourceCodeEnd":2315,"githubUrl":"https://github.com/facebook/relay/blob/668b1b85e06261aa3b58dabfc51f8b5524a70955/compiler/crates/relay-typegen/src/visit.rs#L2279-L2315","documentation":"During typegen, transform_graphql_scalar_type processes fields annotated with a custom scalar directive. When the directive is present but lacks the required path argument (the import path of the JS type module), the compiler panics — the @customScalar directive contract requires both path and export_name.","triggerScenarios":"A @customScalar (CUSTOM_SCALAR_DIRECTIVE_NAME) annotation applied without a path argument, encountered while transforming scalar types in visit.rs during typegen.","commonSituations":"Hand-written or tool-generated scalar annotations missing the path argument; renaming/refactoring that dropped the argument; inconsistent versions between the tool emitting the directive and the compiler.","solutions":["Add the path argument to the custom scalar directive pointing at the module exporting the JS type.","Ensure both path and export_name arguments are present together.","Regenerate the annotation with a current version of the tooling.","Check the expected argument name matches PATH_CUSTOM_SCALAR_ARGUMENT_NAME (exact spelling)."],"exampleFix":"// before\n@customScalar(export_name: \"MyScalarType\")\n// after\n@customScalar(path: \"./src/types/MyScalarType.ts\", export_name: \"MyScalarType\")","handlingStrategy":"validation","validationCode":"// validate custom scalar annotations have both path and export_name\nif (hasCustomScalarDirective(node) && !getArg(node, 'path')) throw new Error('custom scalar directive requires a path argument');","typeGuard":"function hasPathArg(directive) { return directive.arguments?.some(a => a.name.value === 'path'); }","tryCatchPattern":null,"preventionTips":["Always supply path and export_name together on custom scalar directives","Generate annotations with current tooling rather than writing them by hand","Validate directive arguments in a lint step before typegen"],"tags":["typegen","custom-scalar","directive","panic"],"backgroundTag":"missing-directive-argument","analyzedSha":"668b1b85e06261aa3b58dabfc51f8b5524a70955","analyzedAt":"2026-09-02T19:57:20.783Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-10T02:17:09.455Z"}