Skip to content

mkdir errors on already-created dir - #19006

Merged
fdncred merged 2 commits into
nushell:mainfrom
pickx:mkdir-existing
Sep 10, 2026
Merged

fdncred merged 2 commits into
nushell:mainfrom
pickx:mkdir-existing

Conversation

@pickx

@pickx pickx commented Sep 10, 2026

Copy link
Copy Markdown
Contributor

Description

closes #19003. tl;dr: since we always run mkdir with implied --parents, dirs are always created and errors are never thrown. however, we forgot to detect when dirs are not created because they already exist.

note also that we now use translate in the error field when --verbose is passed. this can pretty easily run into #19004 (for example if mktemp was used beforehand). this also keeps the dir name in the error, so you can have something like path: /foo/bar, created: false, error: /foo/bar: File exists. in other words, we repeat the path. tell me if that's not what we want.

User-facing changes (Release notes)

nushell will now error when a dir already exists. nushell's --verbose will no longer report a dir as created when it already exists. however, if multiple dirs are created in the same command (e.g. mkdir dir1 dir2/dir3 dir4) and some of them already exist, the non-existing ones will still be created. this matches the behavior of typical mkdir implementations.

Disclosure

AI was consulted while creating this, but did not generate code.

@fdncred fdncred added notes:fixes Noted in "Bug fixes" section notes:ready Indicates Ready for Release notes labels Sep 10, 2026
@fdncred
fdncred merged commit 954e34d into nushell:main Sep 10, 2026
14 checks passed
@fdncred

fdncred commented Sep 10, 2026

Copy link
Copy Markdown
Contributor

Thanks

@github-actions github-actions Bot added this to the v0.116.0 milestone Sep 10, 2026
@weirdan

weirdan commented Sep 10, 2026

Copy link
Copy Markdown
Contributor

nushell will now error when a dir already exists

This sounds like a serious BC break to me. Previously you could do:

# acts as assertion; the directory will be present after this line (bar any permission errors
mkdir path/to/dir
cp file.name path/to/dir/

and now it would break if path/to/dir is already present.

Also, if we say that nushell's %mkdir is like ^mkdir -p (e.g., from coreutils), then it should be consistent with ^mkdir -p, not bare ^mkdir. And notably, ^mkdir -p does not fail when the folder exists; at least the one from coreutils doesn't:

❯ dpkg -S /usr/bin/mkdir
coreutils: /usr/bin/mkdir

❯ ^mkdir -p path/to/dir

❯ $ans.exit_code
0

❯ ^mkdir -p path/to/dir

❯ $ans.exit_code
0

❯ "path/to/dir" | path exists
true

IMHO, a better way to solve the original issue is to add a new mkdir flag, something like --fail-if-exists.

@fdncred

fdncred commented Sep 10, 2026

Copy link
Copy Markdown
Contributor

Thanks for your input @weirdan. i hadn't considered that. let's revert.

fdncred added a commit that referenced this pull request Sep 10, 2026
Reverts #19006

@pickx if you want to implement a new flag for this functionality
instead of having it as default, have at it.
fdncred pushed a commit that referenced this pull request Sep 16, 2026
…#19021)

# Description

Follow-up to #19003. The default `mkdir` behavior (idempotent,
`-p`-like) stays exactly as-is — #19006 tried making it error by default
and was reverted in #19008, since people rely on `mkdir foo` to just
ensure a directory exists (and `^mkdir -p` doesn't error either). Per
@fdncred's suggestion in the thread, this instead adds an **opt-in**
flag.

With `--fail-if-exists`, `mkdir` errors on a target that already exists
(message `<path>: File exists`, matching coreutils), while still
creating any non-existing targets passed in the same call. Without the
flag, nothing changes.

The `--verbose` `created: true` half of the issue was already fixed in
#19017, so this covers the remaining piece.

# User-Facing Changes

New opt-in switch: `mkdir --fail-if-exists <dir>` (short: none) errors
if the directory already exists instead of silently succeeding. Default
`mkdir` is unchanged.

# Tests + Formatting

Added `commands::umkdir` tests: errors on an existing dir with the flag,
still creates new dirs with the flag, and `-v --fail-if-exists` reports
`created: false`. Existing default-behavior tests (idempotent mkdir,
intermediary dirs) still pass. `cargo fmt --all --check`, `cargo clippy
-p nu-command`, and the `nu-command` test suite are clean.

# After Submitting

Nothing needed (no doc/`std` changes).

---
_Disclosure: I use AI assistance for code review and for drafting text
(English isn't my first language); I review and verify every change
myself before sending it._

---------

Co-authored-by: Claude Opus 4.8 (1M context) <[email protected]>
@cptpiepmatz cptpiepmatz added notes:hide Noted only in "Full Changelog" section and removed notes:fixes Noted in "Bug fixes" section notes:ready Indicates Ready for Release notes labels Sep 26, 2026
@cptpiepmatz

Copy link
Copy Markdown
Member

marked as notes:hide to hide from the changelog as this one got reverted

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

Labels

notes:hide Noted only in "Full Changelog" section

Projects

None yet

Development

Successfully merging this pull request may close these issues.

mkdir doesn't error on already-existing directory

4 participants