DEV Community

Alimkhan Slambek
Alimkhan Slambek

Posted on

A Go Build Failed. I Wanted to Replay It Without the Original Project.

A build log tells you what went wrong. It doesn't always give you what you need to reproduce it.

If a Go build fails on another machine, you might need the exact source files, module dependencies, toolchain, and build settings before you can investigate the same failure locally.

I started building REW to explore a simple idea:

What if you could save a failed build as a file, move it to another machine, and replay it without the original checkout?

It's an open-source CLI written in Go. The first public release is available now, although it's still a pretty limited alpha.

The idea

I wanted a workflow that looks like this:

Build fails → Capture → Transfer → Replay → Compare

Instead of saving only the compiler output, REW collects selected inputs involved in the failed build and packages them into a portable .bfc capsule.

That includes selected workspace files, verified Go module artifacts, build environment metadata, stdout, stderr, and the original exit code.

The capsule can then be verified and replayed inside a Docker container with networking disabled.

The important distinction is that this isn't a VM snapshot or a complete copy of the original machine. REW captures a specific, bounded set of build inputs.

A real example

To test the current alpha, I used a controlled compiler failure in the open-source Cobra project.

I intentionally introduced a compilation error, captured the failed build with REW, and replayed the resulting capsule using Docker without relying on the original checkout.

The failure reproduced in that test.

Here's the terminal recording:

REW capture and replay demo

It's a deliberately broken build, not a production incident. I wanted to establish that the basic workflow worked before asking other developers to try it.

Trying it yourself

Here's a smaller example you can reproduce locally.

You'll need REW v0.1.0-alpha.5, Go 1.26.6, and Docker with Linux AMD64 container support.

Installation instructions and downloadable binaries for macOS ARM64 and Linux AMD64 are in the README.

Once REW is installed, set REW_BIN to the absolute path of its executable.

First, create a minimal project:

mkdir rew-example
cd rew-example

cat > go.mod <<'EOF'
module example.com/rew-quickstart

go 1.26.0
EOF

cat > main.go <<'EOF'
package main

func main() {
    undefinedFunction()
}
EOF
Enter fullscreen mode Exit fullscreen mode

The build will fail because undefinedFunction doesn't exist.

Now capture that failure:

CGO_ENABLED=0 GOOS=linux GOARCH=amd64 GOFLAGS='' \
GOWORK=off GOTOOLCHAIN=local GOPROXY=off GOSUMDB=off \
"$REW_BIN" capture --v3 \
  --include-go-sources \
  -- go build ./...
Enter fullscreen mode Exit fullscreen mode

REW records the failed execution in failure.bfc.

The capture command normally returns the same nonzero exit code as the original failed build. That's expected.

Next, replay the capsule:

"$REW_BIN" replay --v3 --allow-command --memory 1g failure.bfc
Enter fullscreen mode Exit fullscreen mode

For this example, the expected result is:

Original exit code: 1
Replay exit code:   1
Outcome:            reproduced
Replay memory:      1 GiB
Enter fullscreen mode Exit fullscreen mode

REW considers the failure reproduced when its current comparison checks match the original exit code and complete stderr.

It doesn't mean every detail of the original environment was reconstructed.

What happens inside the capsule?

This was one of the more interesting parts of building REW.

A compiler error is usually easy to save as text. The harder part is figuring out what needs to travel with that error so the build can run again elsewhere.

REW's current capture workflow selects Go source files, module metadata, and dependency artifacts under explicit limits.

For external Go modules, it verifies the relevant cached artifacts before including them.

The capsule also contains a manifest and integrity metadata, so replay can check the packaged contents before using them.

For replay, REW reconstructs the required inputs using Docker-managed volumes rather than depending on the original host workspace.

The build then runs inside a Linux AMD64 Docker container with networking disabled.

This doesn't turn Docker into a security sandbox. A capsule still contains executable instructions, and you should only replay capsules from sources you trust.

What doesn't work yet

I'm keeping the first release intentionally narrow.

Right now, the supported workflow is:

  • Go 1.26.6
  • The exact command go build ./...
  • Linux AMD64 Docker replay
  • Selected workspace files and verified external module artifacts
  • Offline replay once the required Docker image is available

There are important limitations.

Active go.work workspaces aren't supported. CGO and custom build tags aren't supported in this workflow either. Some module configurations and build inputs need additional work.

REW also has limits on capsule size, workspace files, and dependency artifacts.

It isn't intended to capture arbitrary CI jobs, and it won't reproduce every build failure.

There's another trade-off: a capsule may contain source code and build metadata. That makes it useful for debugging, but it also means you need to review its contents before sharing it.

The README documents the current limitations in more detail.

What I'm trying to learn next

The controlled examples work, but they don't tell me enough about how REW behaves on other people's projects.

I'm particularly interested in builds involving unusual module layouts, embedded resources, or inputs that the current source discovery misses.

I'd also like to find out whether the capsule workflow is actually useful when debugging a failed build, rather than just technically possible.

If you work with Go and have a project where you can safely reproduce a build failure, I'd appreciate you giving REW a try.

Even a report that says "capture failed at this step" would be helpful.

GitHub: https://github.com/rewtools/rew

It's Apache 2.0 licensed, and the current release is v0.1.0-alpha.5.

Still early days, but I'm curious to see where this approach works and where it falls apart.

Top comments (0)

Some comments may only be visible to logged-in visitors. Sign in to view all comments.