facebook/relay · error
Unable to extract module name.
Error message
Unable to extract module name.
What it means
validate_operation extracts the module name from the operation's source file path (the camel-cased final path segment, used as the required name prefix for operations) and expects extraction to succeed. extract_module_name returns None when the path has no file stem or resolves to a bare index segment with no parent directory, so compiling documents without a usable file path panics.
Source
Thrown at compiler/crates/relay-transforms/src/validations/validate_module_names.rs:35
use thiserror::Error;
pub fn validate_module_names(program: &Program) -> DiagnosticsResult<()> {
(ValidateModuleNames {}).validate_program(program)
}
pub use extract_module_name::extract_module_name;
pub struct ValidateModuleNames {}
impl Validator for ValidateModuleNames {
const NAME: &'static str = "ValidateModuleNames";
const VALIDATE_ARGUMENTS: bool = false;
const VALIDATE_DIRECTIVES: bool = true;
fn validate_operation(&mut self, operation: &OperationDefinition) -> DiagnosticsResult<()> {
let operation_name = operation.name.item.0.to_string();
let path = operation.name.location.source_location().path();
let module_name = extract_module_name(path).expect("Unable to extract module name.");
let (operation_type_suffix, pluralized_string) = match operation.kind {
OperationKind::Query => ("Query", "Queries"),
OperationKind::Mutation => ("Mutation", "Mutations"),
OperationKind::Subscription => ("Subscription", "Subscriptions"),
};
let operation_name_ending_is_valid = operation_name.ends_with("Query")
|| operation_name.ends_with("Mutation")
|| operation_name.ends_with("Subscription");
if !operation_name.starts_with(&module_name) || !operation_name_ending_is_valid
// TODO: T71484519 re-enable this line when queries are correctly named in www
// || !operation_name.ends_with(operation_type_suffix)
{
return Err(vec![Diagnostic::error(
ValidationMessage::InvalidOperationName {
pluralized_string: pluralized_string.to_string(),
operation_type_suffix: operation_type_suffix.to_string(),View on GitHub (pinned to 668b1b85e0)
Solutions
- Compile operations from real files, not stdin/ephemeral buffers, when module-name validation is enabled.
- Rename bare index.js operation files to a meaningful module name (e.g. UserProfile.js) so a module name can be extracted.
- Disable/relax the module-name validation rule if your build uses virtual documents.
- If index files are intentional, ensure they have a parent directory so the helper can fall back to it.
Example fix
// before src/queries/index.js // <- cannot derive module name // after src/queries/UserProfile.js with operation named UserProfileQuery
Defensive patterns
Strategy: validation
Validate before calling
let module_name = extract_module_name(&path)
.ok_or_else(|| Diagnostic::error(format!("Cannot derive module name from path `{path}`; rename the file away from index.*")))?; Type guard
fn has_extractable_module_name(path: &str) -> bool { extract_module_name(path).is_some() } Try / catch
let Some(module_name) = extract_module_name(path) else {
return Err(vec![Diagnostic::error("Unable to extract module name")]);
}; Prevention
- Name operation files after the module (not index.js).
- Compile from real file paths, not stdin/virtual buffers.
- Keep operation names prefixed with the file's module name.
When it happens
Trigger: Compiling an operation from stdin, an in-memory document, or a path whose final segment is "index" with no enclosing directory (get_final_non_index_js_segment returns None), then having the module-name validation run.
Common situations: Tooling that feeds virtual documents (LSP scratch buffers, watchman-less ephemeral files) into the compiler; a query file literally named index.js/index.ts at a path the helper cannot resolve; operations generated without source locations.
Related errors
- commitMutation: Expected mutation operation
- commitMutation: Expected mutation operation
- commitMutation: Expected mutation to be of type request
- unexpected value for @defer if argument: {other:?}
- unexpected value for @stream if argument: {other:?}
AI-assisted analysis of facebook/relay@668b1b85e0 (2026-09-02).
Data as JSON: /api/errors/ead2e9cfcf3776b4.
Report an issue: GitHub.