{"record":{"id":"3ee47587e44bd214","repo":"golangci/golangci-lint","slug":"create-destination-directory-w","errorCode":null,"errorMessage":"create destination directory: %w","messagePattern":"create destination directory: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/commands/internal/builder.go","lineNumber":225,"sourceCode":"func (b Builder) copyBinary(binaryName string) error {\n\tsrc := filepath.Join(b.repo, binaryName)\n\n\tsource, err := os.Open(filepath.Clean(src))\n\tif err != nil {\n\t\treturn fmt.Errorf(\"open source file: %w\", err)\n\t}\n\n\tdefer func() { _ = source.Close() }()\n\n\tinfo, err := source.Stat()\n\tif err != nil {\n\t\treturn fmt.Errorf(\"stat source file: %w\", err)\n\t}\n\n\tif b.cfg.Destination != \"\" {\n\t\terr = os.MkdirAll(b.cfg.Destination, os.ModePerm)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"create destination directory: %w\", err)\n\t\t}\n\t}\n\n\tdst, err := os.OpenFile(filepath.Join(b.cfg.Destination, binaryName), os.O_RDWR|os.O_CREATE|os.O_TRUNC, info.Mode())\n\tif err != nil {\n\t\treturn fmt.Errorf(\"create destination file: %w\", err)\n\t}\n\n\tdefer func() { _ = dst.Close() }()\n\n\t_, err = io.Copy(dst, source)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"copy source to destination: %w\", err)\n\t}\n\n\treturn nil\n}\n","sourceCodeStart":207,"sourceCodeEnd":243,"githubUrl":"https://github.com/golangci/golangci-lint/blob/ed7a235d2d771152056fdc142a9855567c5796a9/pkg/commands/internal/builder.go#L207-L243","documentation":"When cfg.Destination is set, copyBinary creates it (including parents) with os.MkdirAll(..., os.ModePerm) before writing the binary. This error wraps a MkdirAll failure, meaning the destination directory tree could not be created — typically a permissions or path problem (e.g. a non-directory file exists at a path component).","triggerScenarios":"cfg.Destination is non-empty and os.MkdirAll fails: parent path component is an existing regular file, no write permission on an ancestor directory, read-only filesystem, or an invalid/over-long path.","commonSituations":"Destination configured as an existing file instead of a directory, installing to /usr/local/bin without sudo, HOME misconfigured in CI containers, or a typo'd destination path landing on a read-only mount.","solutions":["Check each path component of cfg.Destination — rename/remove any regular file that occupies a directory name","Verify write permission on the closest existing ancestor (or run with elevated privileges / pick a writable destination)","Confirm the destination volume is not mounted read-only","Correct the cfg.Destination value in the configuration to an absolute, valid directory path","Read the wrapped *os.SyscallError: EACCES => permissions, ENOTDIR => file-in-path, EROFS => read-only"],"exampleFix":"// before\ndestination: /usr/local/bin   # needs root\n// after\ndestination: ~/go/bin         # writable without elevation","handlingStrategy":"validation","validationCode":"if dest := cfg.Destination; dest != \"\" {\n    if fi, err := os.Stat(dest); err == nil && !fi.IsDir() {\n        return fmt.Errorf(\"destination %s exists and is not a directory\", dest)\n    }\n    if err := os.MkdirAll(dest, 0o755); err != nil {\n        return fmt.Errorf(\"cannot create destination %s: %w\", dest, err)\n    }\n}\n// also verify write access:\nif dest != \"\" {\n    f, err := os.CreateTemp(dest, \".wcheck*\")\n    if err != nil { return fmt.Errorf(\"destination %s not writable: %w\", dest, err) }\n    f.Close(); os.Remove(f.Name())\n}","typeGuard":null,"tryCatchPattern":"if err := b.copyBinary(name); err != nil {\n    var perr *fs.PathError\n    if errors.As(err, &perr) && errors.Is(perr, fs.ErrPermission) {\n        log.Fatalf(\"cannot create %s: permission denied — choose a writable destination or elevate\", perr.Path)\n    }\n    return err\n}","preventionTips":["Set Destination to an absolute directory path that already exists or is creatable","Never point Destination at an existing regular file","Prefer user-writable dirs (~/go/bin, bin/) over system paths needing root","Check mount status if the destination may be read-only"],"tags":["go","filesystem","mkdir","permissions"],"backgroundTag":"mkdir-permission-denied","analyzedSha":"ed7a235d2d771152056fdc142a9855567c5796a9","analyzedAt":"2026-09-02T18:47:33.865Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}