{"record":{"id":"dea82e379548515a","repo":"JuliusBrussee/caveman","slug":"unknown-usage-link-source-s","errorCode":null,"errorMessage":"unknown usage link source: %s","messagePattern":"unknown usage link source: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"proxy/cmd/caveman-proxy/main.go","lineNumber":637,"sourceCode":"\t\tdefault:\n\t\t\tfatalJSON(logger, fmt.Errorf(\"unknown usage source: %s\", provider))\n\t\t}\n\tcase \"link\", \"refresh\":\n\t\tswitch provider {\n\t\tcase \"\", \"claude\":\n\t\t\tout, err := spend.RefreshClaudeUsageFromEnv()\n\t\t\tif err != nil {\n\t\t\t\tfatalJSON(logger, err)\n\t\t\t}\n\t\t\tprintJSON(out)\n\t\tcase \"codex\":\n\t\t\tout, err := spend.ImportCodex(argFlag(args, \"--path\", \"\"), argFlag(args, \"--since\", \"\"))\n\t\t\tif err != nil {\n\t\t\t\tfatalJSON(logger, err)\n\t\t\t}\n\t\t\tprintJSON(out)\n\t\tdefault:\n\t\t\tfatalJSON(logger, fmt.Errorf(\"unknown usage link source: %s\", provider))\n\t\t}\n\tcase \"unlink\":\n\t\tswitch provider {\n\t\tcase \"claude\", \"anthropic\":\n\t\t\tif err := spend.DeleteQuotaProvider(\"anthropic\"); err != nil {\n\t\t\t\tfatalJSON(logger, err)\n\t\t\t}\n\t\t\tprintJSON(map[string]any{\"unlinked\": \"claude\"})\n\t\tcase \"codex\", \"openai\":\n\t\t\tif err := spend.DeleteQuotaProvider(\"openai\"); err != nil {\n\t\t\t\tfatalJSON(logger, err)\n\t\t\t}\n\t\t\tprintJSON(map[string]any{\"unlinked\": \"codex\"})\n\t\tdefault:\n\t\t\tfatalJSON(logger, fmt.Errorf(\"usage unlink needs claude|codex\"))\n\t\t}\n\tdefault:\n\t\tfatalJSON(logger, fmt.Errorf(\"unknown usage subcommand: %s\", sub))","sourceCodeStart":619,"sourceCodeEnd":655,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/3ee70a102609e550bd2e68004bf5990a9341c851/proxy/cmd/caveman-proxy/main.go#L619-L655","documentation":"Thrown by runUsage's `link`/`refresh` branch: the provider positional must be empty, `claude`, or `codex` (empty defaults to claude). Any other value hits `unknown usage link source: <provider>` because those subcommands only know how to refresh Claude usage from environment credentials or import Codex usage from local files.","triggerScenarios":"`caveman-proxy usage link gemini`, `usage refresh anthropic` (not accepted here even though `unlink` accepts it), `usage link openai`, or typos.","commonSituations":"Confusing the accepted provider sets between subcommands: `link`/`refresh` take claude|codex (or nothing), `unlink` also accepts anthropic/openai aliases, `import` requires an explicit claude|codex; running `refresh anthropic` expecting the alias to carry over.","solutions":["Use `caveman-proxy usage link claude` or `caveman-proxy usage link codex`.","Omit the provider entirely to default to claude: `caveman-proxy usage refresh`.","Map `anthropic`→`claude` and `openai`→`codex` in any wrapper scripts."],"exampleFix":"// before\ncaveman-proxy usage refresh anthropic\n// after\ncaveman-proxy usage refresh claude   # or just: caveman-proxy usage refresh","handlingStrategy":"validation","validationCode":"// shell\ncase \"$PROVIDER\" in \"\"|claude|codex) ;; anthropic) PROVIDER=claude;; openai) PROVIDER=codex;; *) echo \"link/refresh supports claude|codex only\" >&2; exit 2;; esac\ncaveman-proxy usage refresh \"$PROVIDER\"","typeGuard":null,"tryCatchPattern":null,"preventionTips":["link/refresh accept claude|codex (or nothing = claude); aliases like anthropic are only valid on unlink.","Keep per-subcommand provider sets documented in your wrapper scripts.","Omit the provider to get the claude default."],"tags":["cli","invalid-enum-value","usage-link"],"backgroundTag":"invalid-enum-value","analyzedSha":"3ee70a102609e550bd2e68004bf5990a9341c851","analyzedAt":"2026-09-20T15:53:39.229Z","contentChangedAt":"2026-09-20T15:53:39.229Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}