github/copilot-sdk · error
failed to create output directory
Error message
failed to create output directory: %w
What it means
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.
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.
Example fix
// before bundler --output /opt/app/dist // permission denied // after sudo mkdir -p /opt/app/dist && sudo chown $(whoami) /opt/app/dist bundler --output /opt/app/dist
Defensive patterns
Strategy: validation
Validate before calling
if info, err := os.Stat(outputDir); err == nil && !info.IsDir() {
return fmt.Errorf("output path %q exists and is not a directory", outputDir)
}
if err := os.MkdirAll(filepath.Dir(outputDir), 0o755); err != nil {
return fmt.Errorf("cannot prepare output dir %q: %w", outputDir, err)
} Type guard
func isWritableDir(path string) bool {
info, err := os.Stat(path)
if err != nil || !info.IsDir() {
return false
}
f, err := os.CreateTemp(path, ".wtest*")
if err != nil {
return false
}
f.Close()
os.Remove(f.Name())
return true
} Try / catch
artifacts, err := buildBundle(...)
if err != nil {
var pe *fs.PathError
if errors.As(err, &pe) && errors.Is(err, fs.ErrPermission) {
fmt.Fprintf(os.Stderr, "no write access to %s: run as a user with permission or pick another --output\n", pe.Path)
os.Exit(1)
}
return err
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
Background: mkdir permission denied (EACCES): failed to create directory errors explained — this error's family across 32 libraries.
Related errors
- failed to read package directory
- failed to evaluate build constraints in
- failed to hash output binary
- creating runtime asset directory
- joinSession() is intended for extensions running as child…
AI-assisted analysis of github/copilot-sdk@cd8cf15dc3 (2026-09-09).
Data as JSON: /api/errors/1416279e25d4b917.
Report an issue: GitHub.
Appendix: source
Thrown at go/cmd/bundler/main.go:447
}
return bundleArtifacts{outputPath, binaryHash, runtimeArtifactPath, runtimeHash, wrapperArtifactPath, wrapperHash, assetsArtifactPath, assetsHash}, nil
}
// Create temp directory for download
tempDir, err := os.MkdirTemp("", "copilot-bundler-*")
if err != nil {
return bundleArtifacts{}, fmt.Errorf("failed to create temp dir: %w", err)
}
defer os.RemoveAll(tempDir)
binaryPath, tarballPath, err := downloadCLIBinary(info.runtimePlatform, info.binaryName, cliVersion, tempDir)
if err != nil {
return bundleArtifacts{}, fmt.Errorf("failed to download CLI binary: %w", err)
}
if outputDir != "." {
if err := os.MkdirAll(outputDir, 0755); err != nil {
return bundleArtifacts{}, fmt.Errorf("failed to create output directory: %w", err)
}
}
if includeLicense {
if err := extractCLILicense(tarballPath, outputPath); err != nil {
return bundleArtifacts{}, fmt.Errorf("failed to extract CLI license: %w", err)
}
}
binaryHash, err := sha256File(binaryPath)
if err != nil {
return bundleArtifacts{}, fmt.Errorf("failed to hash output binary: %w", err)
}
if err := compressZstdFile(binaryPath, outputPath); err != nil {
return bundleArtifacts{}, fmt.Errorf("failed to write output binary: %w", err)
}
rawLibPath := filepath.Join(tempDir, "runtime.node")
if err := extractFileFromTarball(View on GitHub (pinned to cd8cf15dc3)