{"record":{"id":"d63e40dfbc7acf02","repo":"JuliusBrussee/caveman","slug":"usage-caveman-proxy-learn-apply-sink-id-dry","errorCode":null,"errorMessage":"usage: caveman-proxy learn apply <sink_id> [--dry-run]","messagePattern":"usage: caveman-proxy learn apply <sink_id> \\[--dry-run\\]","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"proxy/cmd/caveman-proxy/main.go","lineNumber":595,"sourceCode":"\t\t\tfatalJSON(logger, err)\n\t\t}\n\t\tout := argFlag(args, \"--out\", store.DefaultLearnReportPath(home))\n\t\tif err := spend.WriteLearnHTML(plan, out); err != nil {\n\t\t\tfatalJSON(logger, err)\n\t\t}\n\t\tsidecar, err := spend.WriteLearnSidecars(home, plan, time.Now(), \"\")\n\t\tif err != nil {\n\t\t\tfatalJSON(logger, err)\n\t\t}\n\t\tif hasArg(args, \"--json\") {\n\t\t\tprintJSON(plan)\n\t\t\treturn\n\t\t}\n\t\tprintJSON(map[string]any{\"report\": out, \"sidecar\": sidecar, \"cave_score\": plan.CaveScore.Score, \"basis\": plan.Basis, \"sinks\": len(plan.Sinks)})\n\tcase \"apply\":\n\t\tsinkID := firstPositional(args)\n\t\tif sinkID == \"\" {\n\t\t\tfatalJSON(logger, fmt.Errorf(\"usage: caveman-proxy learn apply <sink_id> [--dry-run]\"))\n\t\t}\n\t\tplan, err := spend.BuildLearnPlan(cwd, sources, since)\n\t\tif err != nil {\n\t\t\tfatalJSON(logger, err)\n\t\t}\n\t\tapplyLearnSink(logger, home, sinkID, hasArg(args, \"--dry-run\"), plan)\n\tdefault:\n\t\tfatalJSON(logger, fmt.Errorf(\"unknown learn subcommand: %s\", sub))\n\t}\n}\n\nfunc learnRetroOptions(args []string) store.RetroOptions {\n\tbehaviorBudget, _ := strconv.Atoi(argFlag(args, \"--behavior-budget-ms\", \"0\"))\n\tretroBudget, _ := strconv.Atoi(argFlag(args, \"--retro-budget-ms\", \"0\"))\n\treturn store.RetroOptions{\n\t\tEnabled:          hasArg(args, \"--retro\"),\n\t\tBehaviorBudgetMS: behaviorBudget,\n\t\tBudgetMS:         retroBudget,","sourceCodeStart":577,"sourceCodeEnd":613,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/27d5a3981a347890211bb1bf2439e5c821a63bc9/proxy/cmd/caveman-proxy/main.go#L577-L613","documentation":"The `learn apply` subcommand requires a sink_id positional and none was found. fatalJSON prints this usage line (which also documents the optional --dry-run flag) and exits 1 before BuildLearnPlan runs.","triggerScenarios":"`caveman-proxy learn apply --dry-run` with no sink id; flags parsed first leaving no positional; empty SINK shell variable.","commonSituations":"Copy-pasting the example from the apply docs but dropping the id; assuming apply applies all sinks when none given (it does not — one sink per invocation); quoting bugs eating the argument.","solutions":["First run learn scan to list sink ids, then pass one: caveman-proxy learn apply <sink_id> --dry-run","Quote shell variables and assert non-empty in scripts","Prefer a --dry-run first run to validate the sink id cheaply"],"exampleFix":"# before\ncaveman-proxy learn apply --dry-run\n\n# after\ncaveman-proxy learn scan            # find sink ids\ncaveman-proxy learn apply compress-stdin --dry-run","handlingStrategy":"validation","validationCode":"if [ -z \"$SINK_ID\" ]; then echo \"sink id required (see: caveman-proxy learn scan)\" >&2; exit 2; fi\ncaveman-proxy learn apply \"$SINK_ID\" --dry-run","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always learn scan first and copy the sink_id from that output","One sink per apply invocation; there is no apply-all","Use --dry-run as a cheap id check before the real run"],"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"}