{"record":{"id":"2e63a6d30b5170ce","repo":"JuliusBrussee/caveman","slug":"sink-q-not-found-in-current-learn-plan","errorCode":null,"errorMessage":"sink %q not found in current learn plan","messagePattern":"sink %q not found in current learn plan","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"proxy/cmd/caveman-proxy/main.go","lineNumber":629,"sourceCode":"\t\tEnabled:          hasArg(args, \"--retro\"),\n\t\tBehaviorBudgetMS: behaviorBudget,\n\t\tBudgetMS:         retroBudget,\n\t}\n}\n\n// applyLearnSink materializes a candidate edit for a reducible sink under\n// ~/.caveman/candidates/ and returns it. It never edits user config files itself —\n// the analyzer is read-only; the consent-gated editing skill performs real edits.\nfunc applyLearnSink(logger *slog.Logger, home, sinkID string, dryRun bool, plan store.LearnPlan) {\n\tvar target *store.Sink\n\tfor i := range plan.Sinks {\n\t\tif plan.Sinks[i].SinkID == sinkID {\n\t\t\ttarget = &plan.Sinks[i]\n\t\t\tbreak\n\t\t}\n\t}\n\tif target == nil {\n\t\tfatalJSON(logger, fmt.Errorf(\"sink %q not found in current learn plan\", sinkID))\n\t}\n\tvar candidate map[string]any\n\tswitch target.Class {\n\tcase \"reducible\":\n\t\tcandidate = map[string]any{\n\t\t\t\"sink_id\":                        sinkID,\n\t\t\t\"title\":                          target.Title,\n\t\t\t\"class\":                          target.Class,\n\t\t\t\"expected_tokens_per_turn_saved\": target.TokensPerTurn,\n\t\t\t\"suggestion\":                     target.Suggestion,\n\t\t\t\"evidence\":                       target.Evidence,\n\t\t\t\"net_token_negative_gate\":        \"the editing skill must measure before>after tokens/turn and reject any edit that does not reduce them\",\n\t\t\t\"basis\":                          plan.Basis,\n\t\t}\n\tcase \"recurring_context\":\n\t\tcandidate = offloadCandidate(sinkID, target, plan.Basis, plan.Window.Since)\n\tdefault:\n\t\tprintJSON(map[string]any{","sourceCodeStart":611,"sourceCodeEnd":647,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/27d5a3981a347890211bb1bf2439e5c821a63bc9/proxy/cmd/caveman-proxy/main.go#L611-L647","documentation":"applyLearnSink searched plan.Sinks for the given sink_id (exact string match on SinkID) and found nothing. The plan is rebuilt fresh inside this invocation (BuildLearnPlan over the current working directory and since-cutoff), so the id must exist in the plan as computed now, not in an older scan you read from.","triggerScenarios":"Passing a sink id from a previous learn scan after the underlying files/config changed and the sink no longer registers; typo'd or case-mismatched id; running apply from a different cwd than the scan (sinks are cwd-relative), or with a different --since window that excludes the sink's evidence.","commonSituations":"Scan in one directory, apply in another; stale sink list pasted from yesterday's output; --since tightened so the sink's tokens no longer cross the threshold and it drops out of the plan.","solutions":["Re-run caveman-proxy learn scan (same cwd and --since you will use for apply) and copy the sink_id exactly from that output","Run learn apply <sink_id> --dry-run with the freshly scanned id to confirm the match before the real run","Keep scan and apply in the same script/cwd so the plan cannot drift between them"],"exampleFix":"# before (id from an old scan, different cwd)\ncd ~/other && caveman-proxy learn apply old-sink-42\n\n# after (rescan in the target cwd, use current id)\ncd ~/project && caveman-proxy learn scan\ncaveman-proxy learn apply compress-stdin --dry-run","handlingStrategy":"validation","validationCode":"PLAN=$(caveman-proxy learn scan --json)\nSINK_ID=$(echo \"$PLAN\" | jq -r '.sinks[0].sink_id')\n[ -n \"$SINK_ID\" ] && caveman-proxy learn apply \"$SINK_ID\" --dry-run","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Re-scan in the same cwd and with the same --since immediately before apply","Treat scanned sink lists as perishable — files/config changes reshape the plan","Copy ids verbatim; they are exact-match, case-sensitive strings"],"tags":["cli","not-found","learn-plan","stale-state"],"backgroundTag":null,"analyzedSha":"27d5a3981a347890211bb1bf2439e5c821a63bc9","analyzedAt":"2026-08-15T09:26:11.751Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}