JuliusBrussee/caveman · error

usage: caveman-proxy usage import|link|refresh|unlink

Error message

usage: caveman-proxy usage import|link|refresh|unlink <provider>

What it means

runUsage requires a subcommand (import, link, refresh, or unlink) plus a provider argument; with no arguments at all it exits via fatalJSON with the usage line "usage: caveman-proxy usage import|link|refresh|unlink <provider>". It is the entry guard for the usage-tracking command group.

Solutions

  1. Provide one of: import, link, refresh, unlink as the subcommand.
  2. Include the provider argument, e.g. caveman-proxy usage refresh openai.
  3. Consult the usage line in the error to see all valid forms.
  4. Check docs/README for the provider names supported by your installed version.

Example fix

// before
caveman-proxy usage
// after
caveman-proxy usage refresh anthropic
Defensive patterns

Strategy: validation

Validate before calling

valid := map[string]bool{"import": true, "link": true, "refresh": true, "unlink": true}
if len(os.Args) < 3 || !valid[os.Args[2]] {
    fmt.Fprintln(os.Stderr, "usage: caveman-proxy usage import|link|refresh|unlink <provider>")
    os.Exit(2)
}

Try / catch

if err := cmd.Run(); err != nil && strings.Contains(err.Error(), "usage: caveman-proxy usage") {
    // a subcommand + provider is required
}

Prevention

When it happens

Trigger: Running bare `caveman-proxy usage` with no subcommand, before args[0] is even inspected.

Common situations: Users exploring the CLI, omitting the subcommand, or assuming `usage` alone prints a usage report rather than requiring an action verb.

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


AI-assisted analysis of JuliusBrussee/caveman@3ee70a1026 (2026-09-20). Data as JSON: /api/errors/498c468c3238de0c. Report an issue: GitHub.

Appendix: source

Thrown at proxy/cmd/caveman-proxy/main.go:591

	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)
	spend := mustStore(logger, home)
	defer spend.Close()
	provider := firstPositional(args)
	switch sub {
	case "import":
		if provider == "" {
			fatalJSON(logger, fmt.Errorf("usage: caveman-proxy usage import codex|claude"))
		}
		path := argFlag(args, "--path", "")
		since := argFlag(args, "--since", "")
		switch provider {
		case "codex":
			out, err := spend.ImportCodex(path, since)
			if err != nil {

View on GitHub (pinned to 3ee70a1026)