{"record":{"id":"c1699f632f3d05e2","repo":"plandex-ai/plandex","slug":"error-applying-plan-v","errorCode":null,"errorMessage":"error applying plan: %v","messagePattern":"error applying plan: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"app/server/db/result_helpers.go","lineNumber":712,"sourceCode":"\t\t\t\t)\n\n\t\t\t\tif err != nil {\n\t\t\t\t\terrCh <- fmt.Errorf(\"error updating context: %v\", err)\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tupdateContextRes = res\n\t\t\t}\n\t\t\terrCh <- nil\n\n\t\t}()\n\n\t}\n\n\tfor i := 0; i < numRoutines; i++ {\n\t\terr := <-errCh\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"error applying plan: %v\", err)\n\t\t}\n\t}\n\n\t// Store the PlanApply record\n\tplanApply := &PlanApply{\n\t\tId:        uuid.New().String(),\n\t\tOrgId:     orgId,\n\t\tPlanId:    planId,\n\t\tUserId:    userId,\n\t\tCommitMsg: params.CommitMsg,\n\t\tCreatedAt: now,\n\t}\n\n\t// Collect the IDs from the pending results and descriptions\n\tvar resultIds []string\n\tvar descriptionIds []string\n\tvar messageIds []string\n","sourceCodeStart":694,"sourceCodeEnd":730,"githubUrl":"https://github.com/plandex-ai/plandex/blob/e2d772072efadbe41d2946d97d79be55532dbab5/app/server/db/result_helpers.go#L694-L730","documentation":"ApplyPlan aggregates errors from all its worker goroutines through errCh; the first non-nil value received during the numRoutines drain loop is wrapped as \"error applying plan: %v\". This is the outer wrapper for any inner failure — marshalling, file writes, storing descriptions, loading contexts, updating contexts, or a recovered panic — and it aborts the apply before the PlanApply record is persisted.","triggerScenarios":"Any of the ApplyPlan goroutines sends a non-nil error on errCh: result file marshalling/writing failure, StoreDescription failure, LoadContexts failure (new files), UpdateContexts failure (updated files), or a recovered panic; the very first such error is what appears wrapped here.","commonSituations":"Disk full or unwritable results directory; malformed result objects failing JSON marshal; missing file bodies or stale context IDs from an out-of-date plan state; a nil-map panic in the update goroutine; storage permission changes on the org data directory.","solutions":["Unwrap the message to see the inner error (e.g., \"error loading context: ...\", \"error writing result file: ...\", \"panic in ApplyPlan: ...\") and address that root cause.","Check the results/applies directories exist and are writable (os.MkdirAll targets under the org data dir) and that disk space is available.","Re-fetch the plan state and re-load contexts so file bodies and context IDs are current, then retry ApplyPlan.","Ensure only one ApplyPlan runs per plan at a time to avoid races on shared maps and channels.","If a panic is reported, fix the state mismatch it indicates (e.g., updated paths missing from contextsByPath) before retrying."],"exampleFix":"// before: opaque outer error only\nerr := db.ApplyPlan(ctx, params) // error applying plan: <inner>\n\n// after: log/inspect the wrapped cause before retry\nerr := db.ApplyPlan(ctx, params)\nif err != nil {\n    log.Printf(\"apply failed, inner cause: %s\", err) // e.g. 'error loading context: ...'\n    // fix root cause (refresh plan state / check storage), then retry\n}","handlingStrategy":"try-catch","validationCode":"// pre-flight: verify storage is writable and plan state is complete\nif err := os.MkdirAll(resultsDir, 0755); err != nil {\n    return fmt.Errorf(\"storage unavailable: %w\", err)\n}\nif len(planState.CurrentPlanFiles.Files) == 0 {\n    return fmt.Errorf(\"plan state has no files; nothing to apply\")\n}","typeGuard":null,"tryCatchPattern":"err := db.ApplyPlan(ctx, params)\nif err != nil {\n    // err is 'error applying plan: <inner>'; unwrap the inner cause\n    inner := strings.TrimPrefix(err.Error(), \"error applying plan: \")\n    log.Printf(\"ApplyPlan failed, cause: %s\", inner)\n    return fmt.Errorf(\"apply aborted, no PlanApply record written: %w\", err)\n}","preventionTips":["Always read the wrapped inner error — it names the exact failing sub-step.","Pre-validate storage writability and plan state completeness before applying.","Run one ApplyPlan per plan at a time; goroutine races surface here.","Remember the apply is not atomic: on this error, some side-effects may already be persisted, so re-run idempotently or reconcile state."],"tags":["go","plan-apply","error-wrapping","concurrency"],"backgroundTag":"plan-apply-failed","analyzedSha":"e2d772072efadbe41d2946d97d79be55532dbab5","analyzedAt":"2026-09-05T20:56:53.631Z","contentChangedAt":"2026-09-05T20:56:53.631Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}