JuliusBrussee/caveman · error
usage: caveman-proxy trial promote
Error message
usage: caveman-proxy trial promote <optimizer_id> --trial-id <id>
What it means
runTrial's "promote" subcommand requires a positional optimizer_id argument; when it is missing the CLI exits via fatalJSON with a usage string showing the expected form `caveman-proxy trial promote <optimizer_id> --trial-id <id>`. The --trial-id flag is already parsed earlier via requiredTrialID (which has its own error).
Solutions
- Supply the optimizer_id as the first positional argument after `promote`.
- Keep the form: caveman-proxy trial promote <optimizer_id> --trial-id <id>.
- Copy the optimizer_id from the trial export/plan output rather than retyping it.
- Run `caveman-proxy trial --help` (or read the usage error) to confirm argument order.
Example fix
// before caveman-proxy trial promote --trial-id t-123 // after caveman-proxy trial promote opt-42 --trial-id t-123
Defensive patterns
Strategy: validation
Validate before calling
// shell guard
[ -n "$1" ] && [ -n "$TRIAL_ID" ] || { echo 'usage: caveman-proxy trial promote <optimizer_id> --trial-id <id>'; exit 2; } Try / catch
if err := cmd.Run(); err != nil {
if strings.Contains(err.Error(), "usage: caveman-proxy trial promote") {
// missing optimizer_id — prompt user and re-run
}
} Prevention
- Always pass optimizer_id as the first positional after `promote`.
- Script wrappers should assert both optimizer_id and --trial-id before exec.
- Copy both ids from trial export output to avoid omissions.
When it happens
Trigger: Running `caveman-proxy trial promote --trial-id <id>` without the positional optimizer_id, or running `caveman-proxy trial promote` entirely bare (after trial-id defaulting fails or is supplied).
Common situations: Users forget the optimizer id, put it after other flags where the flag parser doesn't pick it up as positional, or copy only the trial id from trial export output.
Understand the failure class
Background: "no subcommand specified" and "... is required": CLI errors when a required argument is missing — this error's family across 13 libraries.
Related errors
- usage: caveman-proxy usage import|link|refresh|unlink
- at least one report path and the canonical span fixture…
- unknown trial subcommand
- unknown usage subcommand
- usage: caveman-agent doctor [--json]
AI-assisted analysis of JuliusBrussee/caveman@3ee70a1026 (2026-09-20).
Data as JSON: /api/errors/2812924960d4735b.
Report an issue: GitHub.
Appendix: source
Thrown at proxy/cmd/caveman-proxy/main.go:577
}
printJSON(map[string]any{"trial_id": trialID, "report": out, "basis": plan.Basis})
case "export":
trialID := requiredTrialID(logger, spend, args)
plan, err := spend.BuildTrialPlan(trialID)
if err != nil {
fatalJSON(logger, err)
}
outDir := argFlag(args, "--out", filepath.Join(home, "exports", "trial-"+trialID))
paths, err := spend.ExportTrial(plan, outDir)
if err != nil {
fatalJSON(logger, err)
}
printJSON(map[string]any{"trial_id": trialID, "export": paths})
case "promote":
trialID := requiredTrialID(logger, spend, args)
optimizerID := firstPositional(args)
if optimizerID == "" {
fatalJSON(logger, fmt.Errorf("usage: caveman-proxy trial promote <optimizer_id> --trial-id <id>"))
}
plan, err := spend.BuildTrialPlan(trialID)
if err != nil {
fatalJSON(logger, err)
}
promoteMove(logger, home, trialID, optimizerID, plan)
default:
fatalJSON(logger, fmt.Errorf("unknown trial subcommand: %s", sub))
}
}
func runUsage(logger *slog.Logger, args []string) {
if len(args) == 0 {
fatalJSON(logger, fmt.Errorf("usage: caveman-proxy usage import|link|refresh|unlink <provider>"))
}
sub := args[0]
args = args[1:]
home := mustHome(logger)View on GitHub (pinned to 3ee70a1026)