JuliusBrussee/caveman · error

usage unlink needs claude|codex

Error message

usage unlink needs claude|codex

What it means

The `usage unlink` subcommand got a provider that is not claude/anthropic or codex/openai. Unlink deletes a quota provider row (DeleteQuotaProvider('anthropic'|'openai')), and only those two backends exist, so anything else exits 1 with this message.

Source

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

			}
			printJSON(out)
		default:
			fatalJSON(logger, fmt.Errorf("unknown usage link source: %s", provider))
		}
	case "unlink":
		switch provider {
		case "claude", "anthropic":
			if err := spend.DeleteQuotaProvider("anthropic"); err != nil {
				fatalJSON(logger, err)
			}
			printJSON(map[string]any{"unlinked": "claude"})
		case "codex", "openai":
			if err := spend.DeleteQuotaProvider("openai"); err != nil {
				fatalJSON(logger, err)
			}
			printJSON(map[string]any{"unlinked": "codex"})
		default:
			fatalJSON(logger, fmt.Errorf("usage unlink needs claude|codex"))
		}
	default:
		fatalJSON(logger, fmt.Errorf("unknown usage subcommand: %s", sub))
	}
}

func runLearn(logger *slog.Logger, args []string) {
	sub := "scan"
	if len(args) > 0 {
		sub = args[0]
		args = args[1:]
	}
	home := mustHome(logger)
	spend := mustStore(logger, home)
	defer spend.Close()
	cwd, _ := os.Getwd()
	sources := strings.Split(argFlag(args, "--sources", "codex,claude,caveman"), ",")
	since := argFlag(args, "--since", "30d")

View on GitHub (pinned to 27d5a3981a)

Solutions

  1. Unlink only claude (or anthropic) or codex (or openai)
  2. If nothing is linked for that provider there is nothing to unlink — verify with your stats/usage read path first
  3. Restrict cleanup scripts to the two supported keys

Example fix

# before
caveman-proxy usage unlink gemini

# after
caveman-proxy usage unlink claude
Defensive patterns

Strategy: validation

Validate before calling

case "$PROVIDER" in claude|anthropic|codex|openai) caveman-proxy usage unlink "$PROVIDER";; *) echo "unlink supports claude|codex" >&2;; esac

Prevention

When it happens

Trigger: `caveman-proxy usage unlink gemini` or any other provider name. Note unlink is the one place aliases are accepted (anthropic→claude, openai→codex), which makes typo'd third names the common residue.

Common situations: Copy-pasting a provider list configured for the gateway (gemini/vertex/bedrock) into unlink; cleanup scripts iterating all known providers instead of the two linkable ones.

Related errors


AI-assisted analysis of JuliusBrussee/caveman@27d5a3981a (2026-08-15). Data as JSON: /api/errors/0289bca6c58531cf. Report an issue: GitHub.