{"record":{"id":"f8fb3207fa0a43e9","repo":"GoogleContainerTools/skaffold","slug":"error-opening-file-w","errorCode":null,"errorMessage":"error opening file: %w","messagePattern":"error opening file: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/skaffold/gcs/client/native.go","lineNumber":102,"sourceCode":"\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()\n\n\turinfo, err := n.parseGCSURI(dst)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tbucket, err := GetBucketManager(ctx, urinfo.Bucket)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tisDirectory, err := n.isGCSDirectory(ctx, bucket, urinfo)\n\tif err != nil {\n\t\treturn err\n\t}\n","sourceCodeStart":84,"sourceCodeEnd":120,"githubUrl":"https://github.com/GoogleContainerTools/skaffold/blob/a1189de023efc32d4b8e11f395acc678aa555011/pkg/skaffold/gcs/client/native.go#L84-L120","documentation":"UploadFile wraps os.Open failures for the local source file before uploading it to GCS. It means the src path could not be opened for reading: it does not exist, is a directory, or the process lacks read permission. The OS error is wrapped with %w so errors.Is/As still work.","triggerScenarios":"Calling Native.UploadFile(ctx, src, dst) where src is missing, is a directory, is a broken symlink, or is unreadable by the current user (e.g. src=\"./config.yaml\" when the file was never created).","commonSituations":"Uploading a generated artifact before the build step produced it; typo in the source path; file deleted by a cleanup step; running with a different working directory than expected; container user lacks read permission on a mounted file.","solutions":["Verify the src path exists and is a regular file (os.Stat) before calling UploadFile; the wrapped error usually says 'no such file or directory'","Fix the path (use an absolute path or ensure the expected working directory)","Grant the process read permission on the file (chmod/chown or run as the owning user)","Check that the build/generation step that produces the file ran before the upload"],"exampleFix":"// before\nn.UploadFile(ctx, \"./out/app.tar.gz\", \"gs://bucket/artifacts/\") // file not built yet\n// after\nif _, err := os.Stat(\"./out/app.tar.gz\"); err != nil {\n    return fmt.Errorf(\"artifact missing, run build first: %w\", err)\n}\nif err := n.UploadFile(ctx, \"./out/app.tar.gz\", \"gs://bucket/artifacts/\"); err != nil { /* handle */ }","handlingStrategy":"validation","validationCode":"func ensureReadableFile(path string) error {\n\tfi, err := os.Stat(path)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"source missing: %w\", err)\n\t}\n\tif fi.IsDir() {\n\t\treturn fmt.Errorf(\"%s is a directory, need a file\", path)\n\t}\n\tf, err := os.Open(path)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"%s not readable: %w\", path, err)\n\t}\n\treturn f.Close()\n}\n// call ensureReadableFile(src) before UploadFile","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Stat the source file before every upload","Ensure the producing build step completes before the upload step","Use absolute paths or set and verify the working directory","Check file permissions in containerized environments"],"tags":["filesystem","gcs","file-io","missing-file"],"backgroundTag":"file-not-found","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"}