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

  1. Compile operations from real files, not stdin/ephemeral buffers, when module-name validation is enabled.
  2. Rename bare index.js operation files to a meaningful module name (e.g. UserProfile.js) so a module name can be extracted.
  3. Disable/relax the module-name validation rule if your build uses virtual documents.
  4. 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

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


AI-assisted analysis of facebook/relay@668b1b85e0 (2026-09-02). Data as JSON: /api/errors/ead2e9cfcf3776b4. Report an issue: GitHub.