github/copilot-sdk · error

failed to write runtime wrapper

Error message

failed to write runtime wrapper: %w

What it means

buildBundle compresses the extracted runtime wrapper into its bundle artifact with Zstandard via compressZstdFile. Failure to read the wrapper or to create/write the compressed artifact is wrapped with this message and stops the bundle. This is the last artifact step before the assets archive.

Solutions

  1. Free space on the output volume or redirect --output to storage with enough headroom.
  2. Ensure the output directory is writable by the build user; pre-create and chown as needed.
  3. Check mount flags (ro) and quotas on the destination filesystem.
  4. Re-run the build; transient write errors may clear on retry.

Example fix

// before
bundler --output /mnt/ro-volume/dist
# read-only filesystem

// after
bundler --output /mnt/rw-volume/dist
Defensive patterns

Strategy: try-catch

Validate before calling

if err := os.MkdirAll(filepath.Dir(wrapperArtifactPath), 0o755); err != nil {
	return fmt.Errorf("artifact dir not creatable: %w", err)
}
probe := wrapperArtifactPath + ".probe"
if err := os.WriteFile(probe, []byte("x"), 0o644); err != nil {
	return fmt.Errorf("artifact path not writable: %w", err)
}
os.Remove(probe)

Type guard

func canWriteTo(dir string) bool {
	f, err := os.CreateTemp(dir, ".probe*")
	if err != nil {
		return false
	}
	f.Close()
	os.Remove(f.Name())
	return true
}

Try / catch

if err := buildBundle(...); err != nil {
	if strings.Contains(err.Error(), "failed to write runtime wrapper") {
		var pe *fs.PathError
		if errors.As(err, &pe) && errors.Is(err, syscall.ENOSPC) {
			log.Error("output volume full while writing wrapper artifact")
		}
		return err
	}
	return err
}

Prevention

When it happens

Trigger: compressZstdFile(rawWrapperPath, wrapperArtifactPath) errors: artifact path unwritable (permissions/read-only mount), disk full, or source wrapper unreadable.

Common situations: Output volume out of space in CI, read-only output mounts in containers, or quota-limited artifact directories.

Understand the failure class

Background: "failed to write file", "Could not save figure", "Error saving remote file" — file write failed: causes and fixes across languages and libraries — this error's family across 38 libraries.

Related errors


AI-assisted analysis of github/copilot-sdk@cd8cf15dc3 (2026-09-09). Data as JSON: /api/errors/0a1439300daafac3. Report an issue: GitHub.

Appendix: source

Thrown at go/cmd/bundler/main.go:496

		return bundleArtifacts{}, fmt.Errorf("failed to write runtime.node: %w", err)
	}

	wrapperName := runtimeWrapperName(info.binaryName)
	rawWrapperPath := filepath.Join(tempDir, wrapperName)
	if err := extractFileFromTarball(
		tarballPath,
		tempDir,
		"package/prebuilds/"+info.runtimePlatform+"/"+wrapperName,
		wrapperName,
	); err != nil {
		return bundleArtifacts{}, fmt.Errorf("runtime package is missing prebuilds/%s/%s: %w", info.runtimePlatform, wrapperName, err)
	}
	wrapperHash, err := sha256File(rawWrapperPath)
	if err != nil {
		return bundleArtifacts{}, fmt.Errorf("failed to hash runtime wrapper: %w", err)
	}
	if err := compressZstdFile(rawWrapperPath, wrapperArtifactPath); err != nil {
		return bundleArtifacts{}, fmt.Errorf("failed to write runtime wrapper: %w", err)
	}
	if err := createRuntimeAssetsArchive(tarballPath, assetsArtifactPath, info); err != nil {
		return bundleArtifacts{}, fmt.Errorf("failed to write runtime assets: %w", err)
	}
	assetsHash, err := sha256File(assetsArtifactPath)
	if err != nil {
		return bundleArtifacts{}, fmt.Errorf("failed to hash runtime assets: %w", err)
	}

	fmt.Printf("Successfully created %s\n", outputPath)
	fmt.Printf("Successfully created %s\n", runtimeArtifactPath)
	fmt.Printf("Successfully created %s\n", wrapperArtifactPath)
	fmt.Printf("Successfully created %s\n", assetsArtifactPath)
	return bundleArtifacts{outputPath, binaryHash, runtimeArtifactPath, runtimeHash, wrapperArtifactPath, wrapperHash, assetsArtifactPath, assetsHash}, nil
}

func filesExist(paths ...string) bool {
	for _, path := range paths {

View on GitHub (pinned to cd8cf15dc3)