t8y2/dbx · critical

start %s: %w

Error message

start %s: %w

What it means

This panic wraps an error from startAgent() during a measured startup iteration. startAgent() fails when the command list is empty, the binary cannot be exec'd (not found, not executable), a stdio pipe cannot be created, or — most commonly — the agent never prints a ready line containing "ready":true on stdout (timed out implicitly by scanner returning false or printing something else). It is thrown with panic because without a started agent the iteration (and thus the benchmark) cannot proceed.

Source

Thrown at agents/drivers/rabbitmq/bench/agent_compare.go:174

				panic(fmt.Errorf("close startup warmup %s: %w", agent.Name, err))
			}
		}
	}

	readySamples := map[string][]float64{}
	handshakeSamples := map[string][]float64{}
	rssSamples := map[string][]int64{}
	readyDurations := map[string]time.Duration{}
	handshakeDurations := map[string]time.Duration{}
	for iteration := 0; iteration < iterations; iteration++ {
		order := agents
		if iteration%2 == 1 {
			order = []agentSpec{agents[1], agents[0]}
		}
		for _, agent := range order {
			process, readyDuration, err := startAgent(agent.Command)
			if err != nil {
				panic(fmt.Errorf("start %s: %w", agent.Name, err))
			}
			handshakeStart := time.Now()
			if _, err := process.call("handshake", map[string]any{}); err != nil {
				process.kill()
				panic(fmt.Errorf("handshake %s: %w", agent.Name, err))
			}
			handshakeDuration := time.Since(handshakeStart)
			readySamples[agent.Name] = append(readySamples[agent.Name], milliseconds(readyDuration))
			handshakeSamples[agent.Name] = append(
				handshakeSamples[agent.Name],
				milliseconds(readyDuration+handshakeDuration),
			)
			rssSamples[agent.Name] = append(rssSamples[agent.Name], readRSSKB(process.command.Process.Pid))
			readyDurations[agent.Name] += readyDuration
			handshakeDurations[agent.Name] += readyDuration + handshakeDuration
			if err := process.close(); err != nil {
				panic(fmt.Errorf("close %s: %w", agent.Name, err))
			}

View on GitHub (pinned to c0390bff16)

Solutions

  1. Verify JAVA_AGENT_JAR and GO_AGENT are set to existing, correct artifact paths before running (requiredEnv already checks non-empty, but not existence).
  2. Run the agent command manually in a shell to see why it fails to reach the ready state.
  3. For the java agent, confirm 'java' is on PATH and the JVM version supports the flags in javaAgentCommand (--add-opens needs Java 9+).
  4. Check the agent's ready-line format still contains "ready":true — update the agent or the harness if the protocol changed.
  5. Check file permissions/execute bit on the GO_AGENT binary.
  6. Replace panic with error return to let the benchmark report per-agent startup failures.

Example fix

// before
process, readyDuration, err := startAgent(agent.Command)
if err != nil {
	panic(fmt.Errorf("start %s: %w", agent.Name, err))
}
// after
process, readyDuration, err := startAgent(agent.Command)
if err != nil {
	return nil, fmt.Errorf("start %s: %w", agent.Name, err)
}
Defensive patterns

Strategy: validation

Validate before calling

// Validate environment and artifacts BEFORE invoking startAgent
for _, key := range []string{"JAVA_AGENT_JAR", "GO_AGENT"} {
	path := os.Getenv(key)
	if strings.TrimSpace(path) == "" {
		log.Fatalf("%s is required", key)
	}
	if _, err := os.Stat(path); err != nil {
		log.Fatalf("%s does not exist: %v", key, err)
	}
}
if _, err := exec.LookPath("java"); err != nil {
	log.Fatal("java not found in PATH")
}
if info, err := os.Stat(os.Getenv("GO_AGENT")); err == nil && info.Mode()&0o111 == 0 {
	log.Fatal("GO_AGENT binary is not executable")
}

Type guard

func agentReady(line string) bool {
	var ready struct {
		Ready bool `json:"ready"`
	}
	return json.Unmarshal([]byte(line), &ready) == nil && ready.Ready
}

Try / catch

func safeStart(command []string, name string) (p *agentProcess, d time.Duration, err error) {
	defer func() {
		if r := recover(); r != nil {
			err = fmt.Errorf("start %s: %v", name, r)
		}
	}()
	return startAgent(command)
}

Prevention

When it happens

Trigger: Called from benchmarkStartups for each measured iteration: startAgent(agent.Command) returns an error — 'empty agent command', exec.Start() failure (e.g. exec: "java": executable file not found in $PATH, permission denied), pipe creation failure, or 'agent did not become ready: ...' when the first stdout line is missing or lacks "ready":true.

Common situations: JAVA_AGENT_JAR/GO_AGENT env vars empty or pointing at a nonexistent file (jar case: java itself starts but the agent prints an error instead of ready); agent binary lacks +x; PATH lacks java; JVM writes a startup error (bad JVM flags, unsupported --add-opens on older Java) so the first line is an error, not ready; slow cold start with the scanner hitting EOF because the agent crashed before ready.

Related errors


AI-assisted analysis of t8y2/dbx@c0390bff16 (2026-09-05). Data as JSON: /api/errors/f999b344bcf9f9ad. Report an issue: GitHub.