{"record":{"id":"1416279e25d4b917","repo":"github/copilot-sdk","slug":"failed-to-create-output-directory-w","errorCode":null,"errorMessage":"failed to create output directory: %w","messagePattern":"failed to create output directory: %w","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"go/cmd/bundler/main.go","lineNumber":447,"sourceCode":"\t\t}\n\t\treturn bundleArtifacts{outputPath, binaryHash, runtimeArtifactPath, runtimeHash, wrapperArtifactPath, wrapperHash, assetsArtifactPath, assetsHash}, nil\n\t}\n\n\t// Create temp directory for download\n\ttempDir, err := os.MkdirTemp(\"\", \"copilot-bundler-*\")\n\tif err != nil {\n\t\treturn bundleArtifacts{}, fmt.Errorf(\"failed to create temp dir: %w\", err)\n\t}\n\tdefer os.RemoveAll(tempDir)\n\n\tbinaryPath, tarballPath, err := downloadCLIBinary(info.runtimePlatform, info.binaryName, cliVersion, tempDir)\n\tif err != nil {\n\t\treturn bundleArtifacts{}, fmt.Errorf(\"failed to download CLI binary: %w\", err)\n\t}\n\n\tif outputDir != \".\" {\n\t\tif err := os.MkdirAll(outputDir, 0755); err != nil {\n\t\t\treturn bundleArtifacts{}, fmt.Errorf(\"failed to create output directory: %w\", err)\n\t\t}\n\t}\n\tif includeLicense {\n\t\tif err := extractCLILicense(tarballPath, outputPath); err != nil {\n\t\t\treturn bundleArtifacts{}, fmt.Errorf(\"failed to extract CLI license: %w\", err)\n\t\t}\n\t}\n\n\tbinaryHash, err := sha256File(binaryPath)\n\tif err != nil {\n\t\treturn bundleArtifacts{}, fmt.Errorf(\"failed to hash output binary: %w\", err)\n\t}\n\tif err := compressZstdFile(binaryPath, outputPath); err != nil {\n\t\treturn bundleArtifacts{}, fmt.Errorf(\"failed to write output binary: %w\", err)\n\t}\n\n\trawLibPath := filepath.Join(tempDir, \"runtime.node\")\n\tif err := extractFileFromTarball(","sourceCodeStart":429,"sourceCodeEnd":465,"githubUrl":"https://github.com/github/copilot-sdk/blob/cd8cf15dc3f9e762615790aaed0a771a0f392755/go/cmd/bundler/main.go#L429-L465","documentation":"buildBundle in the bundler CLI creates the user-supplied output directory with os.MkdirAll (mode 0755) before writing bundle artifacts. If the directory (or any missing parent) cannot be created, the underlying *PathError is wrapped with this message and the bundle aborts. It is skipped when outputDir is \".\" so the error only ever concerns an explicit, non-cwd output directory.","triggerScenarios":"os.MkdirAll(outputDir, 0755) returns an error: permission denied on the target path or a parent, a component of outputDir is an existing regular file (ENOTDIR), outputDir is empty/invalid, or the filesystem is read-only/full.","commonSituations":"Running the bundler without write access to the target (e.g. /opt or another user's directory), passing --output pointing at an existing file instead of a directory, output dir on a read-only CI volume or read-only container filesystem.","solutions":["Check write permission on the output path's parent and run the bundler as a user that can create the directory (or pre-create it with mkdir -p and chown).","If outputDir points at an existing file, remove/rename the file or pass a directory path instead.","Pass --output . to write into the current working directory, which bypasses directory creation entirely.","Verify the filesystem is writable (df/ro mounts) and free disk space is available."],"exampleFix":"// before\nbundler --output /opt/app/dist\n// permission denied\n\n// after\nsudo mkdir -p /opt/app/dist && sudo chown $(whoami) /opt/app/dist\nbundler --output /opt/app/dist","handlingStrategy":"validation","validationCode":"if info, err := os.Stat(outputDir); err == nil && !info.IsDir() {\n\treturn fmt.Errorf(\"output path %q exists and is not a directory\", outputDir)\n}\nif err := os.MkdirAll(filepath.Dir(outputDir), 0o755); err != nil {\n\treturn fmt.Errorf(\"cannot prepare output dir %q: %w\", outputDir, err)\n}","typeGuard":"func isWritableDir(path string) bool {\n\tinfo, err := os.Stat(path)\n\tif err != nil || !info.IsDir() {\n\t\treturn false\n\t}\n\tf, err := os.CreateTemp(path, \".wtest*\")\n\tif err != nil {\n\t\treturn false\n\t}\n\tf.Close()\n\tos.Remove(f.Name())\n\treturn true\n}","tryCatchPattern":"artifacts, err := buildBundle(...)\nif err != nil {\n\tvar pe *fs.PathError\n\tif errors.As(err, &pe) && errors.Is(err, fs.ErrPermission) {\n\t\tfmt.Fprintf(os.Stderr, \"no write access to %s: run as a user with permission or pick another --output\\n\", pe.Path)\n\t\tos.Exit(1)\n\t}\n\treturn err\n}","preventionTips":["Pre-create the output directory with mkdir -p and correct ownership before CI builds.","Never point --output at an existing regular file.","Run the bundler as a non-root user with explicit write access to the target volume.","Check mount ro/ro-remount status and free space on the output volume first."],"tags":["filesystem","mkdir","cli","permission"],"backgroundTag":"mkdir-permission-denied","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"}