juanfont/headscale · warning
extracting logs: %w
Error message
extracting logs: %w
What it means
Wrapped error from extractContainerLogs while saving a container's stdout/stderr logs after an integration-test run. The `hi` test runner extracts artifacts (per AGENTS.md, ~100 MB of logs per run under control_logs/{runID}/) from every hs-*/ts-* container, and this is the outer wrapper around that extraction. The underlying cause is almost always a Docker API call failure (container already removed, daemon unreachable, cancelled context), not the wrapper itself.
Source
Thrown at cmd/hi/docker.go:769
}
}
}
return testRunContainers
}
// extractContainerArtifacts saves logs and tar files from a container.
func extractContainerArtifacts(ctx context.Context, cli *client.Client, containerID, containerName, logsDir string, verbose bool) error {
// Ensure the logs directory exists
err := os.MkdirAll(logsDir, defaultDirPerm)
if err != nil {
return fmt.Errorf("creating logs directory: %w", err)
}
// Extract container logs
err = extractContainerLogs(ctx, cli, containerID, containerName, logsDir, verbose)
if err != nil {
return fmt.Errorf("extracting logs: %w", err)
}
return nil
}
// extractContainerLogs saves the stdout and stderr logs from a container to files.
func extractContainerLogs(ctx context.Context, cli *client.Client, containerID, containerName, logsDir string, verbose bool) error {
// Get container logs
logReader, err := cli.ContainerLogs(ctx, containerID, container.LogsOptions{
ShowStdout: true,
ShowStderr: true,
Timestamps: false,
Follow: false,
Tail: "all",
})
if err != nil {
return fmt.Errorf("getting container logs: %w", err)
}View on GitHub (pinned to 565fd254d0)
Solutions
- Run `docker ps -a --filter name=hs-` to check whether the container still exists; re-run with `go run ./cmd/hi cleanup` first to clear stale state
- Verify the Docker daemon is healthy with `docker info` and restart it if the connection dropped
- Increase the run timeout (runConfig.Timeout) so extraction is not racing a cancelled context
- Read the wrapped error text — it names the exact failing stage (getting logs, demultiplexing, or writing files) which is the real problem
Defensive patterns
Strategy: fallback
Validate before calling
// Before extraction, confirm the container still exists
if _, err := cli.ContainerInspect(ctx, containerID); err != nil {
// skip artifact extraction instead of failing the whole cleanup
log.Printf("container %s gone, skipping log extraction", containerName)
return nil
} Prevention
- Run `go run ./cmd/hi cleanup` before starting a new test run to avoid stale/removed containers
- Treat artifact-extraction failures as non-fatal: the test verdict lives in the test output, not the logs
- Keep disk headroom — each run writes ~100 MB to control_logs/
When it happens
Trigger: Calling extractContainerArtifacts after a test run when the container was force-removed before log extraction (e.g. cleanup ran first), when the Docker daemon connection dropped, or when ctx was cancelled/timed out before cli.ContainerLogs could complete.
Common situations: Stale containers from a previous run that `hi cleanup` already reaped; Docker Desktop restarting mid-run; the run timeout firing and cancelling the context during artifact extraction; disk pressure in the Docker VM.
Related errors
- ensuring image availability: %w
- creating container: %w
- pre-flight checks failed: %w
- cleaning stale test containers: %w
- pruning networks: %w
AI-assisted analysis of juanfont/headscale@565fd254d0 (2026-08-15).
Data as JSON: /api/errors/56dff8409186651b.
Report an issue: GitHub.