JuliusBrussee/caveman · error
go build failed for ${artifact}
Error message
go build failed for ${artifact} What it means
Thrown by the release-binary build script when a `go build` invocation for a release artifact exits with a non-zero status (the child's own compiler output has already been printed to stderr via stdio: "inherit"). The wrapper adds the artifact name because the Go toolchain error alone does not say which GOOS/GOARCH cross-compile target failed.
Source
Thrown at scripts/build-release-binaries.mjs:71
}
return { out, targets: targets.length ? targets : RELEASE_TARGETS, list: false };
}
function build({ out, targets }) {
mkdirSync(out, { recursive: true });
const artifacts = [];
for (const [goos, arch] of targets) {
for (const [name, packagePath] of RELEASE_BINARIES) {
const artifact = releaseArtifactName(name, goos, arch);
const output = join(out, artifact);
process.stderr.write(`build ${artifact}\n`);
const result = spawnSync("go", ["build", "-trimpath", "-o", output, packagePath], {
cwd: root,
env: { ...process.env, CGO_ENABLED: "0", GOOS: goos, GOARCH: arch },
stdio: "inherit",
});
if (result.error) throw result.error;
if (result.status !== 0) throw new Error(`go build failed for ${artifact}`);
artifacts.push(artifact);
}
}
artifacts.sort();
const checksums = artifacts.map((artifact) => {
const digest = createHash("sha256").update(readFileSync(join(out, artifact))).digest("hex");
return `${digest} ${artifact}`;
}).join("\n") + "\n";
writeFileSync(join(out, "checksums.txt"), checksums, { mode: 0o600 });
return artifacts;
}
if (process.argv[1] && resolve(process.argv[1]) === fileURLToPath(import.meta.url)) {
try {
const options = parseArgs(process.argv.slice(2));
if (options.list) process.stdout.write(`${releaseArtifactNames(options.targets).sort().join("\n")}\n`);
else process.stdout.write(`built ${build(options).length} signed-release inputs in ${options.out}\n`);
} catch (error) {View on GitHub (pinned to 27d5a3981a)
Solutions
- Read the go compiler output printed just above the error — it names the actual file/package and cause; fix that first.
- Reproduce manually with the same env: GOOS=<goos> GOARCH=<arch> CGO_ENABLED=0 go build -trimpath -o /tmp/test <packagePath> to iterate faster.
- If a dependency does not support the target, either drop that target via --target or replace/guard the dependency with build tags.
- Ensure a current Go toolchain is installed and `go mod download` succeeds (clean module cache with `go clean -modcache` if it is corrupt).
Example fix
# before: dep uses cgo-only APIs GOOS=windows GOARCH=arm64 go build ./... # fails -> script throws "go build failed for mytool-windows-arm64.exe" # after: guard the dep with build tags //go:build !windows import "github.com/some/cgo-only-lib"
Defensive patterns
Strategy: try-catch
Validate before calling
import { spawnSync } from "node:child_process";
const probe = spawnSync("go", ["version"], { stdio: "pipe" });
if (probe.status !== 0) throw new Error("Go toolchain unavailable — install Go first"); Try / catch
try {
buildRelease({ targets: [["linux", "amd64"]] });
} catch (err) {
if (/^go build failed for /.test(err.message)) {
// artifact name in the message maps to GOOS/GOARCH; the real compiler
// error was already streamed to stderr — surface it, do not retry blindly
process.exitCode = 1;
} else throw err;
} Prevention
- Cross-compile each target locally (GOOS/GOARCH CGO_ENABLED=0 go build) before cutting a release.
- Pin the Go version in CI to the version go.mod requires.
- Run `go mod tidy && go test ./...` before invoking the release script.
When it happens
Trigger: Running the release script where the Go toolchain fails for a specific target: compile errors in the package being built, unsupported GOOS/GOARCH combination for a dependency (e.g. a package using cgo or syscall APIs unavailable on that platform), missing Go toolchain, or a full/corrupt module cache. Note CGO_ENABLED=0 is forced in the env.
Common situations: Adding a dependency that does not cross-compile to windows/arm64 or plan9 etc.; stale go.sum after a dependency bump; Go not installed or an ancient Go version rejecting the go directive in go.mod; building from a clean CI container without a warmed module cache while GOPROXY is misconfigured.
Related errors
- unsupported release target ${JSON.stringify(value)}
- caveman build: dataResidency is not enforced yet; refusing t
- caveman build: requiredFixturePassRate must be in (0,1]
- caveman build: qualityRetention must be in (0,1]
- caveman build: config must export defineBuild()
AI-assisted analysis of JuliusBrussee/caveman@27d5a3981a (2026-08-15).
Data as JSON: /api/errors/53b76b9b31cec75c.
Report an issue: GitHub.