{"record":{"id":"78666c8cf5297441","repo":"github/copilot-sdk","slug":"failed-to-create-output-file-w","errorCode":null,"errorMessage":"failed to create output file: %w","messagePattern":"failed to create output file: %w","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"go/cmd/bundler/main.go","lineNumber":1138,"sourceCode":"\tif strings.HasSuffix(outputPath, \".zst\") {\n\t\treturn strings.TrimSuffix(outputPath, \".zst\") + \".license\"\n\t}\n\treturn outputPath + \".license\"\n}\n\nfunc licenseFileName(binaryName string) string {\n\tif strings.HasSuffix(binaryName, \".zst\") {\n\t\treturn strings.TrimSuffix(binaryName, \".zst\") + \".license\"\n\t}\n\treturn binaryName + \".license\"\n}\n\n// extractFileFromTarballStream writes the current tar entry to disk.\nfunc extractFileFromTarballStream(r io.Reader, destDir, outputName string, mode os.FileMode) error {\n\toutPath := filepath.Join(destDir, outputName)\n\toutFile, err := os.OpenFile(outPath, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, mode)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to create output file: %w\", err)\n\t}\n\tif _, err := io.Copy(outFile, r); err != nil {\n\t\tif cerr := outFile.Close(); cerr != nil {\n\t\t\treturn fmt.Errorf(\"failed to extract license: copy error: %v; close error: %w\", err, cerr)\n\t\t}\n\t\treturn fmt.Errorf(\"failed to extract license: %w\", err)\n\t}\n\treturn outFile.Close()\n}\n\n// extractFileFromTarball extracts a single file from a .tgz into destDir with a new name.\nfunc extractFileFromTarball(tarballPath, destDir, targetPath, outputName string) error {\n\tfile, err := os.Open(tarballPath)\n\tif err != nil {\n\t\treturn err\n\t}\n\tdefer file.Close()\n","sourceCodeStart":1120,"sourceCodeEnd":1156,"githubUrl":"https://github.com/github/copilot-sdk/blob/cd8cf15dc3f9e762615790aaed0a771a0f392755/go/cmd/bundler/main.go#L1120-L1156","documentation":"extractFileFromTarballStream creates the destination file (O_CREATE|O_WRONLY|O_TRUNC) inside destDir before streaming tar contents into it. This error wraps the os.OpenFile failure, so the license (or extracted file) could not be created at outPath.","triggerScenarios":"Called from extractCLILicense when destDir does not exist, the process lacks write permission on destDir or outPath, outPath exists as a directory, or the filesystem is read-only/full.","commonSituations":"Bundler run as unprivileged user against a root-owned output directory; missing parent directory; SELinux/container mounts with read-only output; disk quota exceeded.","solutions":["Create destDir first: os.MkdirAll(destDir, 0o755) before extraction","Verify write permissions on the directory or run as a user with access","Ensure outPath is not an existing directory","Check disk space / read-only mount if EACCES does not apply"],"exampleFix":"// before\nif err := extractCLILicense(tarballPath, outputDir); err != nil { return err }\n// after\nif err := os.MkdirAll(outputDir, 0o755); err != nil { return fmt.Errorf(\"create output dir: %w\", err) }\nif err := extractCLILicense(tarballPath, outputDir); err != nil { return err }","handlingStrategy":"validation","validationCode":"if err := os.MkdirAll(destDir, 0o755); err != nil { return err }\nprobe := filepath.Join(destDir, \".write-probe\")\nif err := os.WriteFile(probe, nil, 0o644); err != nil { return fmt.Errorf(\"dest not writable: %w\", err) }\nos.Remove(probe)","typeGuard":"func canCreateIn(dir string) bool { p := filepath.Join(dir, \".probe\"); if err := os.WriteFile(p, nil, 0o644); err != nil { return false }; os.Remove(p); return true }","tryCatchPattern":"if err := extractCLILicense(tarballPath, outputDir); err != nil {\n    var pe *fs.PathError\n    if errors.As(err, &pe) && (errors.Is(pe.Err, fs.ErrPermission) || errors.Is(pe.Err, fs.ErrNotExist)) {\n        return fmt.Errorf(\"cannot create %s: %w (check dir exists and permissions)\", pe.Path, pe.Err)\n    }\n    return err\n}","preventionTips":["MkdirAll the destination before extraction","Check EACCES early with a probe write","Never point extraction at a path that is already a directory","Check disk space/quota in provisioning scripts"],"tags":["go","file-io","permissions","os-openfile"],"backgroundTag":"file-open-failed","analyzedSha":"cd8cf15dc3f9e762615790aaed0a771a0f392755","analyzedAt":"2026-09-09T18:32:31.973Z","contentChangedAt":"2026-09-09T18:32:31.973Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}