{"record":{"id":"e659b4f3138f0717","repo":"apache/beam","slug":"unable-to-open-file-v","errorCode":null,"errorMessage":"unable to open file %v","messagePattern":"unable to open file (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"sdks/go/pkg/beam/runners/universal/runnerlib/stage.go","lineNumber":146,"sourceCode":"\t\t\t\t\t\tcontinue // so we can get the real error from stream.Recv.\n\t\t\t\t\t}\n\t\t\t\t\treturn errors.Wrapf(err, \"failed to stage file %v\", typePl.GetPath())\n\n\t\t\t\t}\n\t\t\tdefault:\n\t\t\t\treturn errors.Errorf(\"request has unexpected artifact type %s\", typeUrn)\n\t\t\t}\n\n\t\tdefault:\n\t\t\treturn errors.Errorf(\"request has unexpected type %T\", request)\n\t\t}\n\t}\n}\n\nfunc stageFile(filename string, stream jobpb.ArtifactStagingService_ReverseArtifactRetrievalServiceClient) error {\n\tfd, err := os.Open(filename)\n\tif err != nil {\n\t\treturn errors.Wrapf(err, \"unable to open file %v\", filename)\n\t}\n\tdefer fd.Close()\n\n\tdata := make([]byte, 1<<20)\n\tfor {\n\t\tn, err := fd.Read(data)\n\t\tif n > 0 {\n\t\t\tsendErr := stream.Send(&jobpb.ArtifactResponseWrapper{\n\t\t\t\tResponse: &jobpb.ArtifactResponseWrapper_GetArtifactResponse{\n\t\t\t\t\tGetArtifactResponse: &jobpb.GetArtifactResponse{\n\t\t\t\t\t\tData: data[:n],\n\t\t\t\t\t},\n\t\t\t\t}})\n\t\t\tif sendErr == io.EOF {\n\t\t\t\treturn sendErr\n\t\t\t}\n\n\t\t\tif sendErr != nil {","sourceCodeStart":128,"sourceCodeEnd":164,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/go/pkg/beam/runners/universal/runnerlib/stage.go#L128-L164","documentation":"stageFile opens a local artifact file to stream it to the Beam job server during artifact staging in the universal runner. When os.Open fails, the error is wrapped as 'unable to open file %v'. This is the first step of uploading pipeline artifacts over the reverse artifact retrieval gRPC stream.","triggerScenarios":"runnerlib.stageFile (called via stageFiles) is invoked with a path that does not exist, is a directory, lacks read permission, or resides on an unavailable volume, so os.Open returns an error.","commonSituations":"Launching a pipeline to a remote runner (Flink/Spark/Dataflow endpoint) with a stale, relative, or deleted artifact path; the launcher process runs in a container that does not have the artifact mounted.","solutions":["Verify the artifact path exists and is readable from the launching process (os.Stat before launch).","Use absolute paths for artifacts so the launcher does not depend on its working directory.","Check file permissions and that the path is not a directory.","Restore the missing artifact or correct the staging configuration and relaunch."],"exampleFix":"// before\nfd, err := os.Open(filename)\nif err != nil {\n\treturn errors.Wrapf(err, \"unable to open file %v\", filename)\n}\n// after\nif info, statErr := os.Stat(filename); statErr != nil || info.IsDir() {\n\treturn errors.Errorf(\"artifact %q does not exist or is not a regular file\", filename)\n}\nfd, err := os.Open(filename)","handlingStrategy":"validation","validationCode":"if info, err := os.Stat(artifactPath); err != nil || info.IsDir() {\n\treturn fmt.Errorf(\"artifact %q missing or not a regular file\", artifactPath)\n}","typeGuard":"func fileReadable(path string) bool {\n\tf, err := os.Open(path)\n\tif err != nil {\n\t\treturn false\n\t}\n\tf.Close()\n\treturn true\n}","tryCatchPattern":null,"preventionTips":["Pass absolute artifact paths when launching via the universal runner.","Stat all artifacts before submitting the job.","Ensure the launcher has the same filesystem/mounts as the artifact location."],"tags":["go","beam","file-io","artifact-staging"],"backgroundTag":"file-open-failed","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-20T03:17:13.778Z"}