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

  1. 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).
  2. If outputDir points at an existing file, remove/rename the file or pass a directory path instead.
  3. Pass --output . to write into the current working directory, which bypasses directory creation entirely.
  4. 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

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


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)