{"record":{"id":"1b91792ac7b43c40","repo":"golang/go","slug":"error-opening-target-for-caching-w","errorCode":null,"errorMessage":"error opening target for caching: %w","messagePattern":"error opening target for caching: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/cmd/go/internal/work/action.go","lineNumber":512,"sourceCode":"\n\tif err := sh.run(\".\", p.input, nil, cfg.BuildToolexec, base.Tool(\"preprofile\"), \"-o\", a.Target, \"-i\", p.input); err != nil {\n\t\treturn err\n\t}\n\n\t// N.B. Builder.build looks for the out in a.built, regardless of\n\t// whether this came from cache.\n\ta.built = a.Target\n\n\tif !cfg.BuildN {\n\t\t// Cache the output.\n\t\t//\n\t\t// N.B. We don't use updateBuildID here, as preprocessed PGO profiles\n\t\t// do not contain a build ID. updateBuildID is typically responsible\n\t\t// for adding to the cache, thus we must do so ourselves instead.\n\n\t\tr, err := os.Open(a.Target)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"error opening target for caching: %w\", err)\n\t\t}\n\n\t\tc := cache.Default()\n\t\toutputID, _, err := c.Put(a.actionID, r)\n\t\tr.Close()\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"error adding target to cache: %w\", err)\n\t\t}\n\t\tif cfg.BuildX {\n\t\t\tsh.ShowCmd(\"\", \"%s # internal\", joinUnambiguously(str.StringList(\"cp\", a.Target, c.OutputFile(outputID))))\n\t\t}\n\t}\n\n\treturn nil\n}\n\ntype coverProvider struct {\n\t// name of static metadata file fragment emitted by the cover","sourceCodeStart":494,"sourceCodeEnd":530,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/cmd/go/internal/work/action.go#L494-L530","documentation":"In pgoActor.Act, after the preprofile tool writes a preprocessed PGO profile to a.Target, the actor opens it to insert into the build cache. If os.Open(a.Target) fails, the error is wrapped with %w and returned. This is an internal post-build step for PGO (-pgoprofile) inputs.","triggerScenarios":"Running 'go build -pgoprofile=<pprof>' where the preprofile tool reported success but the output file is missing or unreadable when caching begins. Typically an interrupted build, a full tmpdir, or antivirus removing the file.","commonSituations":"Antivirus/quarantine removing the freshly written intermediate; TMPDIR/GOCACHE on a flaky mount; the file was on a path that exceeded a length limit and wasn't actually created.","solutions":["Check dmesg/syslog for the file removal (antivirus, container ephemeral fs).","Ensure GOCACHE and the build temp dir are on a stable writable filesystem.","Re-run the build; if transient, it succeeds; if not, inspect a.Target path length and permissions.","Run with -x to see the exact target path produced by preprofile."],"exampleFix":"// before\n$ go build -pgoprofile=cpu.pprof ./...\n// error: error opening target for caching: open /tmp/.../b001/pprof: no such file\n\n// after — point GOCACHE at a stable local dir\n$ export GOCACHE=$HOME/.cache/go-build\n$ go build -x -pgoprofile=cpu.pprof ./...","handlingStrategy":"validation","validationCode":"// Sanity-check the preprofile output exists before caching.\nfunc verifyPgoTarget(path string) error {\n    fi, err := os.Stat(path)\n    if err != nil { return fmt.Errorf(\"PGO target missing: %w\", err) }\n    if fi.Size() == 0 { return fmt.Errorf(\"PGO target empty: %s\", path) }\n    return nil\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep GOCACHE and TMPDIR on stable writable local storage.","Disable antivirus scanning of the build temp directory.","Watch for path-length limits on Windows when using -pgoprofile."],"tags":["pgo","build-cache","io","profile"],"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-12T12:17:08.281Z"}