{"record":{"id":"07adeee16aa4bc76","repo":"GoogleContainerTools/skaffold","slug":"failed-to-create-directory-v","errorCode":null,"errorMessage":"failed to create directory: %v","messagePattern":"failed to create directory: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/skaffold/gcs/client/native.go","lineNumber":86,"sourceCode":"\t}\n\n\tbucket, err := GetBucketManager(ctx, uriInfo.Bucket)\n\tif err != nil {\n\t\treturn err\n\t}\n\tdefer bucket.Close()\n\n\tfiles, err := n.filesToDownload(ctx, bucket, uriInfo)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tfor uri, localPath := range files {\n\t\tfullPath := filepath.Join(dst, localPath)\n\t\tdir := filepath.Dir(fullPath)\n\t\tif _, err := os.Stat(dir); os.IsNotExist(err) {\n\t\t\tif err := os.MkdirAll(dir, os.ModePerm); err != nil {\n\t\t\t\treturn fmt.Errorf(\"failed to create directory: %v\", err)\n\t\t\t}\n\t\t}\n\n\t\tif err := bucket.DownloadObject(ctx, fullPath, uri); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\treturn nil\n}\n\n// Uploads a single file to the given dst.\nfunc (n *Native) UploadFile(ctx context.Context, src, dst string) error {\n\tf, err := os.Open(src)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"error opening file: %w\", err)\n\t}\n\tdefer f.Close()","sourceCodeStart":68,"sourceCodeEnd":104,"githubUrl":"https://github.com/GoogleContainerTools/skaffold/blob/a1189de023efc32d4b8e11f395acc678aa555011/pkg/skaffold/gcs/client/native.go#L68-L104","documentation":"DownloadRecursive wraps os.MkdirAll failures while recreating the GCS folder structure under the local destination. It means the local destination directories could not be created before downloading an object. The underlying cause (permissions, path conflicts, disk full) is included in the wrapped error.","triggerScenarios":"Calling Native.DownloadRecursive(ctx, src, dst) when filepath.Dir of a destination path exists in the object names but cannot be created: dst (or a path segment) points to a file, the process lacks write permission, or the path is invalid/too long.","commonSituations":"Running skaffold with a remote dependency under a read-only home directory; dst collides with an existing regular file (e.g. dst=./cache and ./cache is a file); running in a container as a non-root user against a root-owned volume; SELinux/AppArmor blocking mkdir.","solutions":["Ensure dst is a writable directory that does not collide with an existing file (check the wrapped %v for 'permission denied', 'not a directory', etc.)","Pre-create the destination with os.MkdirAll(dst, os.ModePerm) and verify it succeeds before calling DownloadRecursive","Run as a user with write access to dst, or chown/chmod the target directory","Check disk space and filesystem errors (ENOSPC, EROFS) indicated in the wrapped error"],"exampleFix":"// before\ncwd, _ := os.Getwd()\nn.DownloadRecursive(ctx, \"gs://bucket/dir/**\", \"./cache\") // ./cache is a regular file\n// after\nif err := os.RemoveAll(\"./cache\"); err != nil { /* handle */ }\nif err := os.MkdirAll(\"./cache\", os.ModePerm); err != nil { /* handle */ }\nif err := n.DownloadRecursive(ctx, \"gs://bucket/dir/**\", \"./cache\"); err != nil { /* handle */ }","handlingStrategy":"validation","validationCode":"func ensureWritableDir(dst string) error {\n\tif fi, err := os.Stat(dst); err == nil && !fi.IsDir() {\n\t\treturn fmt.Errorf(\"%s exists and is not a directory\", dst)\n\t}\n\tif err := os.MkdirAll(dst, os.ModePerm); err != nil {\n\t\treturn fmt.Errorf(\"cannot create %s: %w\", dst, err)\n\t}\n\tprobe := filepath.Join(dst, \".write-probe\")\n\tif err := os.WriteFile(probe, nil, 0o644); err != nil {\n\t\treturn fmt.Errorf(\"%s is not writable: %w\", dst, err)\n\t}\n\treturn os.Remove(probe)\n}\n// call ensureWritableDir(dst) before DownloadRecursive","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always pre-create and probe-writable the dst directory before recursive downloads","Never point dst at a path occupied by a regular file","Run downloads as a user with ownership of the destination volume","Watch for ENOSPC; check free space before large recursive downloads"],"tags":["filesystem","gcs","directory-creation","permissions"],"backgroundTag":"mkdir-permission-denied","analyzedSha":"a1189de023efc32d4b8e11f395acc678aa555011","analyzedAt":"2026-09-05T12:09:27.064Z","contentChangedAt":"2026-09-05T12:09:27.064Z","schemaVersion":2},"datasetVersion":"2026-09-12T17:17:11.597Z"}