{"record":{"id":"498c468c3238de0c","repo":"JuliusBrussee/caveman","slug":"usage-caveman-proxy-usage-import-link-refresh-unl","errorCode":null,"errorMessage":"usage: caveman-proxy usage import|link|refresh|unlink <provider>","messagePattern":"usage: caveman-proxy usage import\\|link\\|refresh\\|unlink <provider>","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"proxy/cmd/caveman-proxy/main.go","lineNumber":469,"sourceCode":"\tcase \"promote\":\n\t\ttrialID := requiredTrialID(logger, spend, args)\n\t\toptimizerID := firstPositional(args)\n\t\tif optimizerID == \"\" {\n\t\t\tfatalJSON(logger, fmt.Errorf(\"usage: caveman-proxy trial promote <optimizer_id> --trial-id <id>\"))\n\t\t}\n\t\tplan, err := spend.BuildTrialPlan(trialID)\n\t\tif err != nil {\n\t\t\tfatalJSON(logger, err)\n\t\t}\n\t\tpromoteMove(logger, home, trialID, optimizerID, plan)\n\tdefault:\n\t\tfatalJSON(logger, fmt.Errorf(\"unknown trial subcommand: %s\", sub))\n\t}\n}\n\nfunc runUsage(logger *slog.Logger, args []string) {\n\tif len(args) == 0 {\n\t\tfatalJSON(logger, fmt.Errorf(\"usage: caveman-proxy usage import|link|refresh|unlink <provider>\"))\n\t}\n\tsub := args[0]\n\targs = args[1:]\n\thome := mustHome(logger)\n\tspend := mustStore(logger, home)\n\tdefer spend.Close()\n\tprovider := firstPositional(args)\n\tswitch sub {\n\tcase \"import\":\n\t\tif provider == \"\" {\n\t\t\tfatalJSON(logger, fmt.Errorf(\"usage: caveman-proxy usage import codex|claude\"))\n\t\t}\n\t\tpath := argFlag(args, \"--path\", \"\")\n\t\tsince := argFlag(args, \"--since\", \"\")\n\t\tswitch provider {\n\t\tcase \"codex\":\n\t\t\tout, err := spend.ImportCodex(path, since)\n\t\t\tif err != nil {","sourceCodeStart":451,"sourceCodeEnd":487,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/27d5a3981a347890211bb1bf2439e5c821a63bc9/proxy/cmd/caveman-proxy/main.go#L451-L487","documentation":"runUsage was invoked with no arguments at all, so there is no subcommand to dispatch (import/link/refresh/unlink). It fails fast with the usage string rather than defaulting to any behavior, and exits 1 via fatalJSON.","triggerScenarios":"Bare `caveman-proxy usage` with nothing after it — typically a wrapper script that failed to interpolate its argument, or an exploratory run to 'see what it does' (use --help instead).","commonSituations":"Empty shell variable expansion (`caveman-proxy usage $CMD` with CMD unset); cron/systemd unit with a missing argument; users expecting a no-arg default like 'show stats'.","solutions":["Provide the subcommand and provider: caveman-proxy usage import claude","Guard wrapper scripts: skip or fail clearly when the command variable is empty","Use the binary's help output to enumerate valid subcommands"],"exampleFix":"# before\ncaveman-proxy usage\n\n# after\ncaveman-proxy usage import claude   # correct binary: caveman-proxy usage import claude","handlingStrategy":"validation","validationCode":"if [ $# -eq 0 ]; then echo \"usage: caveman-proxy usage import|link|refresh|unlink <provider>\" >&2; exit 2; fi","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Guard wrapper scripts against empty command variables","Use --help for discovery instead of bare invocations","Treat a bare-subcommand exit 1 as a script bug, not a runtime condition"],"tags":["cli","usage-error","exit-1"],"backgroundTag":null,"analyzedSha":"27d5a3981a347890211bb1bf2439e5c821a63bc9","analyzedAt":"2026-08-15T09:26:11.751Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}