{"record":{"id":"d9b70ba28420fcab","repo":"plandex-ai/plandex","slug":"failed-to-write-s-s","errorCode":null,"errorMessage":"failed to write %s: %s","messagePattern":"failed to write (.+?): (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"app/cli/lib/apply.go","lineNumber":689,"sourceCode":"\t\t\t\t\ttoRevert[dstPath] = types.ApplyReversion{Content: string(bytes), Mode: mode}\n\t\t\t\t\tmu.Unlock()\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tmu.Lock()\n\t\t\t\tupdatedFiles = append(updatedFiles, path)\n\t\t\t\ttoRemoveOnRollback = append(toRemoveOnRollback, dstPath)\n\t\t\t\tmu.Unlock()\n\t\t\t\t// Create the directory if it doesn't exist\n\t\t\t\terr := os.MkdirAll(filepath.Dir(dstPath), 0755)\n\t\t\t\tif err != nil {\n\t\t\t\t\terrCh <- fmt.Errorf(\"failed to create directory %s: %s\", filepath.Dir(dstPath), err.Error())\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Write the file\n\t\t\terr = os.WriteFile(dstPath, []byte(content), 0644)\n\t\t\tif err != nil {\n\t\t\t\terrCh <- fmt.Errorf(\"failed to write %s: %s\", dstPath, err.Error())\n\t\t\t\treturn\n\t\t\t}\n\t\t\terrCh <- nil\n\t\t}(path, content)\n\t}\n\n\tfor path, remove := range toRemove {\n\t\tgo func(path string, remove bool) {\n\t\t\tif !remove {\n\t\t\t\terrCh <- nil\n\t\t\t\treturn\n\t\t\t}\n\t\t\t// Compute destination path\n\t\t\tdstPath := filepath.Join(fs.ProjectRoot, path)\n\t\t\t// Check if the file exists\n\t\t\tvar exists bool\n\t\t\tvar mode os.FileMode\n\t\t\tinfo, err := os.Stat(dstPath)","sourceCodeStart":671,"sourceCodeEnd":707,"githubUrl":"https://github.com/plandex-ai/plandex/blob/e2d772072efadbe41d2946d97d79be55532dbab5/app/cli/lib/apply.go#L671-L707","documentation":"After ensuring the directory exists, ApplyFiles writes the plan content with os.WriteFile(dstPath, content, 0644). A failure here (permissions, read-only FS, disk full, target is a directory) is wrapped into this error and aborts the apply.","triggerScenarios":"os.WriteFile(dstPath, []byte(content), 0644) returns an error — write permission denied, dstPath is a directory, disk full, read-only filesystem, or immutable file attribute.","commonSituations":"File owned by root or another user without write permission; target path is actually a directory; container/CI filesystem mounted read-only; quota exceeded on a large generated file.","solutions":["Fix write permissions/ownership on the target file or its directory (chmod/chown)","Verify dstPath is not a directory; remove the conflicting directory if the plan intends a file","Check disk space (df -h) and remount read-only volumes as read-write","Remove the immutable attribute (chattr -i) if set"],"exampleFix":"// before\n-rw-r--r-- 1 root root config.yaml   # plan overwrites it as non-root\n// after\n$ sudo chown $USER config.yaml\n$ plandex apply","handlingStrategy":"validation","validationCode":"// pre-check writability\nif info, err := os.Stat(dstPath); err == nil {\n  if info.IsDir() { return fmt.Errorf(\"%s is a directory\", dstPath) }\n  f, err := os.OpenFile(dstPath, os.O_WRONLY, 0)\n  if err != nil { return fmt.Errorf(\"%s not writable: %w\", dstPath, err) }\n  f.Close()\n}\nif err := syscall.Access(filepath.Dir(dstPath), syscall.W_OK); err != nil {\n  return fmt.Errorf(\"directory not writable\")\n}","typeGuard":"func isWritablePath(path string) bool {\n  return syscall.Access(path, syscall.W_OK) == nil\n}","tryCatchPattern":"if err := os.WriteFile(dstPath, content, 0o644); err != nil {\n  if errors.Is(err, fs.ErrPermission) { /* fix perms */ }\n  if errors.Is(err, fs.ErrExist) { /* path is a dir */ }\n  return fmt.Errorf(\"write %s: %w\", dstPath, err)\n}","preventionTips":["Check df -h for full disks before applying","Fix ownership of files generated by root/docker as the same user as Plandex","Never mount the project read-only when applying","Verify target is a file, not a directory"],"tags":["go","filesystem","write","permissions"],"backgroundTag":"file-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"}