Skip to content

posixfs: a name below a non-directory object does not exist - #228

Merged
ThomasWaldmann merged 1 commit into
borgbackup:mainfrom
ThomasWaldmann:posixfs-notadirectory
Sep 24, 2026
Merged

ThomasWaldmann merged 1 commit into
borgbackup:mainfrom
ThomasWaldmann:posixfs-notadirectory

Conversation

@ThomasWaldmann

Copy link
Copy Markdown
Member

Accessing a name whose parent is an object (a file) behaved differently depending on the platform. An example is config/config when config is a file, which is what borg 2 sees when it opens a borg 1.x repository.

  • POSIX: info / load / delete / hash raised a raw NotADirectoryError (ENOTDIR, not wrapped). The REST server turned that into an HTTP 500, so the REST client raised a requests.HTTPError.
  • Windows: the OS reports such a path as not found, so the same access gave ObjectNotFound (and an HTTP 404 via REST).

This PR treats NotADirectoryError like FileNotFoundError in posixfs info, load, delete and hash. posixfs (and REST in front of posixfs) now behaves the same on all platforms, as sftp and s3 already do: OpenSSH's sftp-server reports ENOTDIR as "no such file", and s3 has no directories.

rmdir / list keep raising NotADirectoryError. For those, it means the name itself is not a directory, not that the name doesn't exist.

rclone is not changed. With a local-path remote, rclone answers ENOTDIR with HTTP 500 (which also gets retried), so it raises BackendError. Matching rclone's error text would be fragile, so the new test skips rclone with a TODO. Cloud remotes have no directories, so they are not affected.

Test: test_parent_is_an_object runs on all tested backends. It fails for posixfs and REST without this change and passes with it.

Motivation: borg can then detect a borg 1.x repository with a plain except ObjectNotFound instead of a catch-all except Exception, see borgbackup/borg#10418.

🤖 Generated with Claude Code

Accessing a name whose parent is an object (a file), e.g. "config/config" when
"config" is a file, raised a raw NotADirectoryError from info/load/delete/hash
on POSIX, and the REST server turned that into an HTTP 500. On Windows, the OS
reports such a path as not found, so the same access gave ObjectNotFound there.

Treat NotADirectoryError like FileNotFoundError in info, load, delete and hash,
so posixfs (and REST via posixfs) behaves the same on all platforms, like sftp
and s3 already do.

rmdir/list keep raising NotADirectoryError: there, it means that the name itself
is not a directory, not that it does not exist.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@ThomasWaldmann ThomasWaldmann changed the title posixfs: a name below an object does not exist posixfs: a name below a non-directory object does not exist Sep 24, 2026
@ThomasWaldmann
ThomasWaldmann merged commit c53c026 into borgbackup:main Sep 24, 2026
9 checks passed
@ThomasWaldmann
ThomasWaldmann deleted the posixfs-notadirectory branch September 24, 2026 18:14
ThomasWaldmann added a commit to ThomasWaldmann/borg that referenced this pull request Sep 24, 2026
…detection

borgstore 0.6.4 (borgbackup/borgstore#228) reports a name below an object as
ObjectNotFound on all platforms (posixfs raised a raw NotADirectoryError on
POSIX, which the REST server turned into an HTTP 500), so a borg 1.x repository
now always takes the ObjectNotFound branch of _load_config.

Remove the "except Exception" branch and only catch backend and OS errors
around the probe of the config file.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.

1 participant