Skip to content

Fix incorrect claim that a module file cannot match its directory name - #2219

Merged
fdncred merged 1 commit into
nushell:mainfrom
davidpavlovschi:docs/module-naming-restriction
Aug 6, 2026
Merged

Fix incorrect claim that a module file cannot match its directory name#2219
fdncred merged 1 commit into
nushell:mainfrom
davidpavlovschi:docs/module-naming-restriction

Conversation

@davidpavlovschi

Copy link
Copy Markdown
Contributor

What

book/modules/creating_modules.md says:

Module files and commands cannot be named after parent module

A .nu file cannot have the same name as its module directory (e.g., spam/spam.nu) as this would create an ambiguous condition with the name being defined twice.

Nushell accepts that layout. There is no error and no ambiguity condition. What Nushell actually rejects is an export whose name equals the module name — a command, alias, known external, or a submodule declared by name.

This PR replaces the false statement with the real restriction, and keeps a note explaining why spam/spam.nu is still worth avoiding (the submodule's main is shadowed by the parent module's main).

Verified against Nushell 0.114.1 (Homebrew)

$ nu --version
0.114.1
  1. A .nu file with the same name as its directory imports fine on its own:

    $ printf 'export def hello [] { "hi from spam/spam.nu" }\n' > spam/spam.nu
    $ nu --no-config-file -c 'use spam/spam.nu *; hello'
    hi from spam/spam.nu
    
  2. It also works as a submodule exported from spam/mod.nu:

    # spam/mod.nu
    export module ./spam.nu
    export def top [] { "top" }
    
    $ nu --no-config-file -c 'use spam *; print (spam hello); print (top)'
    hi from spam/spam.nu
    top
    

    Behaviour is identical to a differently-named submodule (foo/bar.nu), so nothing is "defined twice" and nothing errors.

  3. The one real gotcha, which the new note documents: if both the parent module and the same-named submodule export a main, both resolve to the same command name and the parent silently wins — still no error:

    $ nu --no-config-file -c 'use spam *; spam'
    parent main
    
  4. The restriction that does exist, and that the corrected text describes:

    $ nu --no-config-file -c 'module spam { export module spam { } }'
    Error: nu::parser::named_as_module
    
      x Can't export module named same as the module.
       ,-[source:1:29]
     1 | module spam { export module spam { } }
       :                             ^^|^
       :                               `-- can't export from module spam
       `----
      help: Module spam can't export module named the same as the module. Either
            change the module name, or export `mod` module.
    

    Same for export def spam, export alias spam, and export extern spam inside module spam. This matches crates/nu-parser/src/parse_module.rs, parse_def.rs and parse_alias.rs (ParseError::NamedAsModule) and the not_allowed_submodule / module_invalid_def_name / module_invalid_alias_name / module_invalid_known_external_name tests in tests/modules/mod.rs in nushell/nushell.

    export const spam = 1 inside module spam is accepted, so the corrected text deliberately does not list constants.

Checks run

  • npx prettier@3 --check book/modules/creating_modules.md — passes.
  • Each example above was executed against nu 0.114.1; the error text in the new code block is copied from real output.

Translations

zh-CN/book/modules/creating_modules.md:432 and ko/book/modules/creating_modules.md:430 carry the same incorrect sentence. Following the repository's translation workflow, this PR only changes the English page and leaves those to the usual nu tools/i18n.nu outdated <locale> sync.

Disclosure

This change was drafted with AI assistance (Claude). Every behavioural claim in it was verified by running the commands shown above against Nushell 0.114.1 and by reading the parser source and test suite in nushell/nushell.

The 'Creating Modules' chapter stated that a `.nu` file cannot have the
same name as its module directory (e.g. `spam/spam.nu`). Nushell accepts
that layout: the file imports normally, both directly (`use spam/spam.nu`)
and as a submodule exported from `spam/mod.nu`.

The restriction that does exist is on the exported *name*: a module cannot
export a command, alias, or known external defined inside it, or a submodule
declared by name, with the same name as the module itself.

Replace the false statement with the real restriction, and keep a note
warning that a same-named submodule is still worth avoiding because its
`main` is shadowed by the parent module's `main`.
@fdncred
fdncred merged commit 022eddf into nushell:main Aug 6, 2026
2 checks passed
@fdncred

fdncred commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants