Skip to content

os: Root.RemoveAll error does not name correct filepath #82509

Open

Description

@valoq

Go version

go version go1.27.3 linux/amd64

Output of go env in your module/workspace:

AR='ar'
CC='gcc'
CGO_CFLAGS='-O2 -g'
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_ENABLED='1'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
CXX='g++'
GCCGO='gccgo'
GO111MODULE=''
GOAMD64='v1'
GOARCH='amd64'
GOAUTH='netrc'
GOBIN='/home/user/.local/go/bin'
GOCACHE='/home/user/.cache/go-build'
GOCACHEPROG=''
GODEBUG=''
GOENV='/home/user/.config/go/env'
GOEXE=''
GOEXPERIMENT='nodwarf5'
GOFIPS140='off'
GOFLAGS=''
GOGCCFLAGS='-fPIC -m64 -pthread -Wl,--no-gc-sections -fmessage-length=0 -ffile-prefix-map=/tmp/go-build2228693577=/tmp/go-build -gno-record-gcc-switches'
GOHOSTARCH='amd64'
GOHOSTOS='linux'
GOINSECURE=''
GOMOD='/dev/null'
GOMODCACHE='/home/user/.local/go/pkg/mod'
GONOPROXY=''
GONOSUMDB=''
GOOS='linux'
GOPACKAGESDRIVER=''
GOPATH='/home/user/.local/go'
GOPRIVATE=''
GOPROXY='https://proxy.golang.org,direct'
GOROOT='/usr/lib/go'
GOSUMDB='sum.golang.org'
GOTELEMETRY='local'
GOTELEMETRYDIR='/home/user/.config/go/telemetry'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOTOOLDIR='/usr/lib/go/pkg/tool/linux_amd64'
GOVCS=''
GOVERSION='go1.27.3-X:nodwarf5'
GOWORK=''
PKG_CONFIG='pkg-config'

What did you do?

This example removes a directory with a read-only subdirectory, once with os.RemoveAll and once with Root.RemoveAll for comparison.
Both fail on the same file but only os.RemoveAll reports the correct file path.

package main

import (
        "fmt"
        "os"
)

func main() {
        // test/dir/locked/file where locked is read-only
        os.MkdirAll("test/dir/locked", 0o755)
        os.WriteFile("test/dir/locked/file", nil, 0o644)
        os.Chmod("test/dir/locked", 0o555)

        fmt.Println(os.RemoveAll("test/dir"))

        root, err := os.OpenRoot("test")
        if err != nil {
                panic(err)
        }
        fmt.Println(root.RemoveAll("dir"))
}

What did you see happen?

os.RemoveAll: unlinkat test/dir/locked/file: permission denied
Root.RemoveAll:  RemoveAll dir: permission denied

Root.RemoveAll reports only the name it was given and the caller cannot tell which entry could not be removed. All other similar functiosn report the correct path like os.RemoveAll does

What did you expect to see?

Root.RemoveAll should correctly report the full path of the file that triggered the error, like or.RemoveAll and others do.
there was a related bug in os.RemoveAll reported in #30491

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions