JuliusBrussee/caveman · error
optimizer not found in trial
Error message
optimizer %q not found in trial %s
What it means
promoteMove (proxy/cmd/caveman-proxy/main.go:945) searches the trial plan's Moves for an entry whose OptimizerID matches the requested optimizer. If no move matches, the zero-value move has an empty OptimizerID and the command aborts with this error. It means the optimizer id does not exist in the given trial's plan — a lookup failure, not a state problem.
Solutions
- List the trial plan's moves (e.g. the trial report/plan command) and copy an exact OptimizerID
- Double-check --trial-id points at the trial that actually contains this optimizer
- Re-run the trial plan build if the plan was regenerated and the id no longer exists
- Check for typos/case differences in the optimizer identifier
Example fix
// before caveman-proxy trial promote --trial-id 2026-09-20-a --optimizer compress-0pt // after (id that exists in the plan) caveman-proxy trial promote --trial-id 2026-09-20-a --optimizer context-compress.v1
Defensive patterns
Strategy: validation
Validate before calling
plan, err := store.LoadTrialPlan(home, trialID)
if err != nil { return err }
found := false
for _, m := range plan.Moves {
if m.OptimizerID == optimizerID { found = true; break }
}
if !found {
return fmt.Errorf("optimizer %q not in trial %s; available: %v", optimizerID, trialID, idsOf(plan.Moves))
} Prevention
- Copy optimizer ids from the trial plan output verbatim instead of retyping
- Confirm --trial-id matches the trial that produced the optimizer
- Keep the trial plan report open when promoting moves
- Watch for regenerated plans changing optimizer ids
When it happens
Trigger: Calling the trial promote flow (runTrial → promoteMove) with --optimizer <id> where <id> is not one of the OptimizerID values in the stored TrialPlan for the supplied --trial-id.
Common situations: Typo or casing mismatch in the optimizer id; referencing an optimizer from a different trial's plan; the trial plan was regenerated and the optimizer id changed; stale docs listing an old optimizer id.
Understand the failure class
Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.
Related errors
- no trial_id supplied and no trial runs exist
- caveman-cloud MCP changed after setup; refusing destructive…
- caveman-cloud MCP changed during interrupted setup…
- caveman-cloud MCP changed during interrupted removal…
- caveman-cloud MCP postflight mismatch
AI-assisted analysis of JuliusBrussee/caveman@3ee70a1026 (2026-09-20).
Data as JSON: /api/errors/14312572bcd89160.
Report an issue: GitHub.
Appendix: source
Thrown at proxy/cmd/caveman-proxy/main.go:945
if err != nil {
fatalJSON(logger, err)
}
if latest == "" {
fatalJSON(logger, fmt.Errorf("no trial_id supplied and no trial runs exist"))
}
return latest
}
func promoteMove(logger *slog.Logger, home, trialID, optimizerID string, plan store.TrialPlan) {
var move store.TrialMove
for _, candidate := range plan.Moves {
if candidate.OptimizerID == optimizerID {
move = candidate
break
}
}
if move.OptimizerID == "" {
fatalJSON(logger, fmt.Errorf("optimizer %q not found in trial %s", optimizerID, trialID))
}
if move.Status != "safe_now" || !(strings.HasPrefix(move.SafetyClass, "S0_") || strings.HasPrefix(move.SafetyClass, "S1_")) {
path := filepath.Join(home, "reports", "caveman-trial-"+trialID+"-"+optimizerID+"-candidate.yaml")
if err := os.MkdirAll(filepath.Dir(path), 0o700); err != nil {
fatalJSON(logger, err)
}
raw, _ := yaml.Marshal(map[string]any{
"mode": "record",
"optimizers": map[string]bool{optimizerID: true},
"eval_command": "caveman evals run",
})
if err := os.WriteFile(path, raw, 0o600); err != nil {
fatalJSON(logger, err)
}
printJSON(map[string]any{
"trial_id": trialID, "optimizer_id": optimizerID, "promoted": false,
"candidate_config": path, "eval_command": "caveman evals run",
"reason": "move is not safe_now S0/S1",View on GitHub (pinned to 3ee70a1026)