{"record":{"id":"4a5fdaa0dd0f5ce1","repo":"plandex-ai/plandex","slug":"error-initializing-plan-dir-v","errorCode":null,"errorMessage":"error initializing plan dir: %v","messagePattern":"error initializing plan dir: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"app/server/db/plan_helpers.go","lineNumber":82,"sourceCode":"\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"error inserting lockable plan id: %v\", err)\n\t\t}\n\n\t\t// the one place where we do this to skip the locking queue\n\t\t// ok to cheat this once since we're creating a new plan\n\t\trepo := getGitRepo(orgId, plan.Id)\n\t\t_, err = CreateBranch(repo, plan, nil, \"main\", tx)\n\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"error creating main branch: %v\", err)\n\t\t}\n\n\t\tlog.Println(\"Created branch main\")\n\n\t\terr = InitPlan(orgId, plan.Id)\n\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"error initializing plan dir: %v\", err)\n\t\t}\n\n\t\tlog.Println(\"Initialized plan dir\")\n\n\t\treturn nil\n\t})\n\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn plan, nil\n}\n\nfunc ListOwnedPlans(projectIds []string, userId string, archived bool) ([]*Plan, error) {\n\tqs := \"SELECT * FROM plans WHERE project_id = ANY($1) AND owner_id = $2\"\n\tqargs := []interface{}{pq.Array(projectIds), userId}\n","sourceCodeStart":64,"sourceCodeEnd":100,"githubUrl":"https://github.com/plandex-ai/plandex/blob/e2d772072efadbe41d2946d97d79be55532dbab5/app/server/db/plan_helpers.go#L64-L100","documentation":"This error wraps a failure from InitPlan(orgId, plan.Id) in CreatePlan (app/server/db/plan_helpers.go:82). InitPlan creates the plan's working directory structure on disk after the git 'main' branch exists. A failure here means the DB transaction rolled back even though the plan row, lockable id, and branch creation succeeded within the transaction, leaving possible orphaned on-disk artifacts.","triggerScenarios":"Calling CreatePlan when the plan directory cannot be created (insufficient permissions on the storage root, disk full, path too long), when a directory for the same plan id already exists with conflicting contents, or when InitPlan's internal file writes fail mid-way.","commonSituations":"Read-only or full volume hosting plan data, running the server as a user without write access to the plan storage root, leftover directories from an earlier failed CreatePlan, or container storage limits being hit.","solutions":["Inspect the wrapped %v message and server logs for the underlying os-level error (permission denied, no space left on device)","Fix filesystem permissions and free disk space on the plan storage volume","Remove the orphaned plan directory for the failed plan id, then retry CreatePlan","Add a pre-flight check in CreatePlan that the storage root is writable before starting the transaction"],"exampleFix":"// before\nerr = InitPlan(orgId, plan.Id)\nif err != nil {\n    return fmt.Errorf(\"error initializing plan dir: %v\", err)\n}\n// after (fail fast with wrapped cause and clean stale dir)\nif err := InitPlan(orgId, plan.Id); err != nil {\n    os.RemoveAll(getPlanDir(orgId, plan.Id))\n    return fmt.Errorf(\"error initializing plan dir: %w\", err)\n}","handlingStrategy":"validation","validationCode":"// Go: verify the plan dir parent is writable before CreatePlan\nplansDir := getPlansBaseDir()\nif fi, err := os.Stat(plansDir); err != nil || !fi.IsDir() {\n    return fmt.Errorf(\"plans dir %s missing\", plansDir)\n}\nif err := syscall.Access(plansDir, os.O_RDWR); err != nil {\n    return fmt.Errorf(\"plans dir not writable: %w\", err)\n}","typeGuard":"func dirWritable(path string) bool {\n    fi, err := os.Stat(path)\n    return err == nil && fi.IsDir() && unix.Access(path, unix.W_OK) == nil\n}","tryCatchPattern":"plan, err := db.CreatePlan(ctx, orgId, projectId, userId, name)\nif err != nil {\n    if strings.Contains(err.Error(), \"error initializing plan dir\") {\n        if _, statErr := os.Stat(planDirPath); statErr == nil {\n            os.RemoveAll(planDirPath) // drop orphaned dir; DB tx already rolled back\n        }\n        return nil, fmt.Errorf(\"plan dir init failed; cleaned up and can retry: %w\", err)\n    }\n    return nil, err\n}","preventionTips":["Alert on low disk space for the plan storage volume","Verify write permissions after changing the server's run user or container image","Remove orphaned plan directories before retrying CreatePlan","Pre-create and validate the directory skeleton the server needs at startup"],"tags":["filesystem","permissions","disk","plan-creation"],"backgroundTag":"directory-initialization-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"}