github/copilot-sdk · error

LinuxMuslCliHash must be a SHA-256 hash

Error message

LinuxMuslCliHash must be a SHA-256 hash (%d bytes), got %d bytes

What it means

When Config.LinuxMuslCli is provided (an alternate musl-static CLI binary for Linux), Setup requires its companion LinuxMuslCliHash to be a valid 32-byte SHA-256 digest; otherwise it panics. Optional assets carry mandatory hashes whenever present so installs can be verified.

Solutions

  1. Set LinuxMuslCliHash to the raw 32-byte sha256.Sum256 of the LinuxMuslCli bytes
  2. Use hex.DecodeString if the digest is only available as hex text
  3. Verify pairing: LinuxMuslCli bytes and LinuxMuslCliHash must come from the same artifact
  4. Guard before Setup: if cfg.LinuxMuslCli != nil && len(hash) != sha256.Size { fix }

Example fix

// before
Setup(Config{LinuxMuslCli: muslReader, LinuxMuslCliHash: []byte(hexDigest)})
// after
raw, _ := hex.DecodeString(hexDigest)
Setup(Config{LinuxMuslCli: muslReader, LinuxMuslCliHash: raw})
Defensive patterns

Strategy: validation

Validate before calling

if linuxMuslCli != nil && len(linuxMuslCliHash) != sha256.Size {
	return errors.New("LinuxMuslCliHash must be raw 32-byte SHA-256")
}

Prevention

When it happens

Trigger: Calling Setup with a non-nil LinuxMuslCli but a LinuxMuslCliHash that is empty, hex-encoded as raw bytes, truncated, or otherwise not exactly sha256.Size bytes.

Common situations: Adding musl build support and wiring the binary but forgetting the hash field, reusing the wrong asset's hash, or passing a hex string where raw digest bytes are expected.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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

Appendix: source

Thrown at go/internal/embeddedcli/embeddedcli.go:73

	LinuxMuslRuntimeExecutableHash []byte
	LinuxMuslRuntimeNode           io.Reader
	LinuxMuslRuntimeNodeHash       []byte
	LinuxMuslRuntimeAssets         io.Reader
	LinuxMuslRuntimeAssetsHash     []byte

	Dir     string
	Version string
}

func Setup(cfg Config) {
	if cfg.Cli == nil {
		panic("Cli reader is required")
	}
	if len(cfg.CliHash) != sha256.Size {
		panic(fmt.Sprintf("CliHash must be a SHA-256 hash (%d bytes), got %d bytes", sha256.Size, len(cfg.CliHash)))
	}
	if cfg.LinuxMuslCli != nil && len(cfg.LinuxMuslCliHash) != sha256.Size {
		panic(fmt.Sprintf("LinuxMuslCliHash must be a SHA-256 hash (%d bytes), got %d bytes", sha256.Size, len(cfg.LinuxMuslCliHash)))
	}
	if cfg.LinuxMuslRuntimeLib != nil && len(cfg.LinuxMuslRuntimeLibHash) != sha256.Size {
		panic(fmt.Sprintf("LinuxMuslRuntimeLibHash must be a SHA-256 hash (%d bytes), got %d bytes", sha256.Size, len(cfg.LinuxMuslRuntimeLibHash)))
	}
	validateRuntimePairConfig(cfg.RuntimeExecutable, cfg.RuntimeExecutableHash, cfg.RuntimeNode, cfg.RuntimeNodeHash, "")
	validateRuntimePairConfig(cfg.LinuxMuslRuntimeExecutable, cfg.LinuxMuslRuntimeExecutableHash, cfg.LinuxMuslRuntimeNode, cfg.LinuxMuslRuntimeNodeHash, "LinuxMusl")
	validateOptionalHash(cfg.RuntimeAssets, cfg.RuntimeAssetsHash, "RuntimeAssetsHash")
	validateOptionalHash(cfg.LinuxMuslRuntimeAssets, cfg.LinuxMuslRuntimeAssetsHash, "LinuxMuslRuntimeAssetsHash")
	setupMu.Lock()
	defer setupMu.Unlock()
	if setupDone {
		panic("Setup must only be called once")
	}
	if pathInitialized {
		panic("Setup must be called before Path is accessed")
	}
	config = cfg
	setupDone = true

View on GitHub (pinned to cd8cf15dc3)