facebook/relay · error
Expected @{} directive to have an export_name argument
Error message
Expected @{} directive to have an export_name argument What it means
Companion to the path-argument panic: when the custom scalar directive is present, its export_name argument (the exported JS type's name) is mandatory. If arguments.named(EXPORT_NAME_CUSTOM_SCALAR_ARGUMENT_NAME) returns None, the compiler panics instead of generating broken output.
Source
Thrown at compiler/crates/relay-typegen/src/visit.rs:2315
panic!(
"Expected @{} directive to have a path argument",
*CUSTOM_SCALAR_DIRECTIVE_NAME
)
})
.expect_string_literal();
let import_path = typegen_context.project_config.js_module_import_identifier(
&typegen_context
.project_config
.artifact_path_for_definition(typegen_context.definition_source_location),
&PathBuf::from(path.lookup()),
);
let export_name = directive
.arguments
.named(ArgumentName(*EXPORT_NAME_CUSTOM_SCALAR_ARGUMENT_NAME))
.unwrap_or_else(|| {
panic!(
"Expected @{} directive to have an export_name argument",
*CUSTOM_SCALAR_DIRECTIVE_NAME
)
})
.expect_string_literal();
custom_scalars.insert((export_name, PathBuf::from(import_path.lookup())));
return AST::RawType(export_name);
}
// TODO: We could implement custom variables that are provided via the
// config by inserting them into the schema with directives, thus avoiding
// having two different ways to express typed custom scalars internally.
if let Some(custom_scalar) = typegen_context
.project_config
.typegen_config
.custom_scalar_types
.get(&scalar_name.item)
{
match custom_scalar {View on GitHub (pinned to 668b1b85e0)
Solutions
- Add the export_name argument naming the exported JS type for the scalar.
- Verify the argument spelling matches the compiler constant (export_name).
- Keep path and export_name always supplied together in the directive.
- Update the emitting tool to a version that always writes both arguments.
Example fix
// before @customScalar(path: "./src/types/MyScalarType.ts") // after @customScalar(path: "./src/types/MyScalarType.ts", export_name: "MyScalarType")
Defensive patterns
Strategy: validation
Validate before calling
if (hasCustomScalarDirective(node) && !getArg(node, 'export_name')) throw new Error('custom scalar directive requires an export_name argument'); Type guard
function hasExportNameArg(directive) { return directive.arguments?.some(a => a.name.value === 'export_name'); } Prevention
- Treat path + export_name as an atomic pair in the directive
- Review hand-edited or generated annotations in code review
- Keep the annotation-emitting tool updated to emit both arguments
When it happens
Trigger: transform_graphql_scalar_type encounters a custom scalar directive that has a path argument but no export_name argument while generating type information.
Common situations: Partially written annotations; refactors that removed export_name; hand-edited generated/introspection data; tooling that only emits one of the two required arguments.
Related errors
- Expected @{} directive to have a path argument
- Expected the JS type for '{}' to be defined, please update '
- @__metadata directive should have only one argument!
- Expected to have a typegen operation for `{normal_name}`
- unknown @catch `to` value. Use `NULL` or `RESULT` (default)
AI-assisted analysis of facebook/relay@668b1b85e0 (2026-09-02).
Data as JSON: /api/errors/c918da9f20b4f38f.
Report an issue: GitHub.