juanfont/headscale · error

executing test: %w

Error message

executing test: %w

What it means

Generic wrapper returned when `streamAndWait` reports an error while streaming output from or waiting on the test container. It covers both the `ContainerLogs` failure path ('getting container logs') and the `ContainerWait` failure path ('waiting for container'), so the wrapped message tells you which half broke. `exitCode` is -1 whenever this fires, meaning the container's real exit status is unknown.

Source

Thrown at cmd/hi/docker.go:193

			log.Printf("Warning: post-test cleanup failed: %v", cleanErr)
		}

		// Clean up artifacts from successful tests to save disk space in CI
		if exitCode == 0 {
			if config.Verbose {
				log.Printf("Test succeeded, cleaning up artifacts to save disk space...")
			}

			cleanErr := cleanupSuccessfulTestArtifacts(logsDir, config.Verbose)

			if cleanErr != nil && config.Verbose {
				log.Printf("Warning: artifact cleanup failed: %v", cleanErr)
			}
		}
	}

	if err != nil {
		return fmt.Errorf("executing test: %w", err)
	}

	if exitCode != 0 {
		return fmt.Errorf("%w: exit code %d", ErrTestFailed, exitCode)
	}

	log.Printf("Test completed successfully!")

	return nil
}

// buildGoTestCommand constructs the go test command arguments.
func buildGoTestCommand(config *RunConfig) []string {
	cmd := []string{"go", "test", "./..."}

	if config.TestPattern != "" {
		cmd = append(cmd, "-run", config.TestPattern)
	}

View on GitHub (pinned to 565fd254d0)

Solutions

  1. Check Docker daemon health and recent events: `docker events --since 30m` and daemon logs.
  2. Make sure no concurrent cleanup (`hi clean`, scheduled `docker prune`) runs during the test.
  3. Read the wrapped message: 'getting container logs' vs 'waiting for container' points to attach vs wait APIs.
  4. Re-run the test once the daemon is stable; capture `control_logs/<runID>/` for artifacts if it recurs.
Defensive patterns

Strategy: retry

Validate before calling

// confirm the daemon is responsive and the container exists before the run
if err := cli.Ping(ctx); err != nil {
    return fmt.Errorf("docker daemon unreachable: %w", err)
}

Try / catch

err := runDockerTest(ctx, config)
if err != nil && !errors.Is(err, ErrTestFailed) && !errors.Is(err, ErrMemoryLimitViolations) {
    // infrastructure-style failure (streaming/waiting): safe to retry once after daemon check
}

Prevention

When it happens

Trigger: `cli.ContainerLogs` fails to attach (daemon disconnect, container already removed by a concurrent cleanup), or `cli.ContainerWait`'s error channel fires (context cancelled, daemon restart, container killed unexpectedly).

Common situations: Docker daemon restarting mid-run; someone runs `docker rm -f` / `hi cleanup` while a test streams; CI machine suspending and dropping the daemon socket; per-command context timeout too short.

Related errors


AI-assisted analysis of juanfont/headscale@565fd254d0 (2026-08-15). Data as JSON: /api/errors/60056de1f05469d3. Report an issue: GitHub.