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
- Verify JAVA_AGENT_JAR and GO_AGENT are set to existing, correct artifact paths before running (requiredEnv already checks non-empty, but not existence).
- Run the agent command manually in a shell to see why it fails to reach the ready state.
- For the java agent, confirm 'java' is on PATH and the JVM version supports the flags in javaAgentCommand (--add-opens needs Java 9+).
- Check the agent's ready-line format still contains "ready":true — update the agent or the harness if the protocol changed.
- Check file permissions/execute bit on the GO_AGENT binary.
- 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
- Stat every artifact path and exec.LookPath every binary before the run.
- Keep the agent's ready-line contract ("ready":true) documented and versioned.
- Run the agent once manually to confirm it reaches ready in the target environment.
- Verify JVM version supports all flags in javaAgentCommand (e.g. --add-opens requires Java 9+).
- Set an explicit readiness timeout in startAgent instead of relying on scanner EOF.
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
- warm up handshake %s: %w
- close startup warmup %s: %w
- handshake %s: %w
- close %s: %w
- DBX_PUBLIC_BASE_PATH contains invalid characters
AI-assisted analysis of t8y2/dbx@c0390bff16 (2026-09-05).
Data as JSON: /api/errors/f999b344bcf9f9ad.
Report an issue: GitHub.