{"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":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"proxy/cmd/caveman-proxy/main.go","lineNumber":515,"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":497,"sourceCodeEnd":533,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/27d5a3981a347890211bb1bf2439e5c821a63bc9/proxy/cmd/caveman-proxy/main.go#L497-L533","documentation":"Under `usage link`/`usage refresh`, the provider positional was not one of the accepted values (empty/claude, codex) and the dispatch hit the default arm, exiting 1. Empty provider is allowed here (defaults to claude), so this specifically means a non-empty unrecognized value.","triggerScenarios":"Running `caveman-proxy usage link gemini`, `usage refresh anthropic`, or any third provider name. Only claude and codex have refresh/import implementations in this build.","commonSituations":"New providers added to the proxy config but not to usage linking; scripts looping over all configured providers and hitting one without a usage source; alias confusion (anthropic works for unlink but not link).","solutions":["Use claude (or empty) or codex for link/refresh","Check `caveman-proxy usage link` output/docs for the supported set in your binary version","Filter your provider loop to the supported set before calling"],"exampleFix":"# before\nfor p in claude codex gemini vertex; do caveman-proxy usage link $p; done\n\n# after\nfor p in claude codex; do caveman-proxy usage link $p; done","handlingStrategy":"validation","validationCode":"case \"$PROVIDER\" in \"\"|claude|codex) caveman-proxy usage link \"$PROVIDER\";; *) echo \"unsupported link source: $PROVIDER\" >&2;; esac","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Remember empty provider defaults to claude for link/refresh — you rarely need to pass it","Restrict provider loops to claude and codex","Aliases accepted by unlink are not accepted by link; keep the sets straight"],"tags":["cli","usage-error","provider-validation","exit-1"],"backgroundTag":null,"analyzedSha":"27d5a3981a347890211bb1bf2439e5c821a63bc9","analyzedAt":"2026-08-15T09:26:11.751Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}