{"record":{"id":"371375a91a865eca","repo":"plandex-ai/plandex","slug":"error-writing-original-files-to-temp-dir-v","errorCode":null,"errorMessage":"error writing original files to temp dir: %v","messagePattern":"error writing original files to temp dir: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"app/server/db/diff_helpers.go","lineNumber":83,"sourceCode":"\t\t\t\tif err != nil {\n\t\t\t\t\terrCh <- fmt.Errorf(\"error creating directory: %v\", err)\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\terr = os.WriteFile(filepath.Join(tempDirPath, path), []byte(context.Body), 0644)\n\t\t\t\tif err != nil {\n\t\t\t\t\terrCh <- fmt.Errorf(\"error writing file: %v\", err)\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t}\n\t\t\terrCh <- nil\n\t\t}(path, context)\n\t}\n\n\tfor range planState.ContextsByPath {\n\t\terr = <-errCh\n\t\tif err != nil {\n\t\t\treturn \"\", fmt.Errorf(\"error writing original files to temp dir: %v\", err)\n\t\t}\n\t}\n\n\tif hasAnyOriginal {\n\t\t// add and commit the files in the temp dir\n\t\terr := gitAdd(tempDirPath, \".\")\n\t\tif err != nil {\n\t\t\treturn \"\", fmt.Errorf(\"error adding files to git repository for dir: %s, err: %v\", tempDirPath, err)\n\t\t}\n\n\t\terr = gitCommit(tempDirPath, \"original files\")\n\t\tif err != nil {\n\t\t\treturn \"\", fmt.Errorf(\"error committing files to git repository for dir: %s, err: %v\", tempDirPath, err)\n\t\t}\n\t}\n\n\t// write the current files to the temp dir\n\terrCh = make(chan error, len(files))","sourceCodeStart":65,"sourceCodeEnd":101,"githubUrl":"https://github.com/plandex-ai/plandex/blob/e2d772072efadbe41d2946d97d79be55532dbab5/app/server/db/diff_helpers.go#L65-L101","documentation":"This is the aggregation point: the parent goroutine drains errCh once per entry in ContextsByPath, and any non-nil error sent by a worker (directory creation, file write, or recovered panic) is wrapped with this prefix and returned from GetPlanDiffs. It indicates one of the original-file versions could not be materialized in the temp git repo.","triggerScenarios":"Any per-path goroutine for planState.ContextsByPath sends a non-nil error (from [362], [363], or [361]); the first error received aborts the whole diff computation.","commonSituations":"Same real-world causes as the inner errors: full disk, permission loss, deleted temp dir, panics on nil contexts; often seen on hosts with constrained /tmp or corrupted plan state.","solutions":["Read the inner error after the prefix — it identifies the actual root cause (mkdir/write/panic) and the failing path.","Fix that root cause per its own guidance (space, permissions, path sanitization, nil checks).","Note the loop returns early without draining remaining workers; consider draining all errors to avoid leaked goroutine sends (buffered channel already prevents goroutine leaks).","Add per-path context to the wrapped message for easier triage."],"exampleFix":"// before\nreturn \"\", fmt.Errorf(\"error writing original files to temp dir: %v\", err)\n// after\nreturn \"\", fmt.Errorf(\"error writing original files to temp dir: %w\", err) // use %w to allow errors.As/Is unwrapping","handlingStrategy":"try-catch","validationCode":"if len(planState.ContextsByPath) == 0 {\n    // nothing to diff from contexts; short-circuit or handle\n}","typeGuard":null,"tryCatchPattern":"diffs, err := GetPlanDiffs(orgId, planId, plain)\nif err != nil {\n    var inner error\n    if strings.Contains(err.Error(), \"error writing original files to temp dir: \") {\n        inner = errors.New(strings.TrimPrefix(err.Error(), \"error writing original files to temp dir: \"))\n        log.Printf(\"inner cause: %v\", inner)\n    }\n    return fmt.Errorf(\"plan diff unavailable: %w\", err)\n}","preventionTips":["Fix the underlying mkdir/write/panic error reported after the prefix — this error is only a wrapper.","Use %w instead of %v when wrapping so callers can errors.Unwrap to the root cause.","Consider reporting which path failed by including it in worker error messages.","Keep the error channel buffered (it is) so a single failure cannot leak goroutines."],"tags":["concurrency","error-wrapping","filesystem"],"backgroundTag":"temp-dir-write-failed","analyzedSha":"e2d772072efadbe41d2946d97d79be55532dbab5","analyzedAt":"2026-09-05T20:56:53.631Z","contentChangedAt":"2026-09-05T20:56:53.631Z","schemaVersion":2},"datasetVersion":"2026-09-12T22:17:10.623Z"}