plandex-ai/plandex · error

failed to create directory %s: %s

Error message

failed to create directory %s: %s

What it means

During plan apply, os.MkdirAll fails to create the parent directory of a file being written (dstPath). Typically a permission problem or a path component that exists as a non-directory (e.g. a file where a folder is expected).

Source

Thrown at app/cli/lib/apply.go:682

				if string(bytes) == content {
					// log.Println("File is unchanged, skipping")
					errCh <- nil
					return
				} else {
					mu.Lock()
					updatedFiles = append(updatedFiles, path)
					toRevert[dstPath] = types.ApplyReversion{Content: string(bytes), Mode: mode}
					mu.Unlock()
				}
			} else {
				mu.Lock()
				updatedFiles = append(updatedFiles, path)
				toRemoveOnRollback = append(toRemoveOnRollback, dstPath)
				mu.Unlock()
				// Create the directory if it doesn't exist
				err := os.MkdirAll(filepath.Dir(dstPath), 0755)
				if err != nil {
					errCh <- fmt.Errorf("failed to create directory %s: %s", filepath.Dir(dstPath), err.Error())
					return
				}
			}
			// Write the file
			err = os.WriteFile(dstPath, []byte(content), 0644)
			if err != nil {
				errCh <- fmt.Errorf("failed to write %s: %s", dstPath, err.Error())
				return
			}
			errCh <- nil
		}(path, content)
	}

	for path, remove := range toRemove {
		go func(path string, remove bool) {
			if !remove {
				errCh <- nil
				return

View on GitHub (pinned to e2d772072e)

Solutions

  1. Remove/rename any regular file that occupies a directory position in the target path
  2. Check disk space (df -h) and quota
  3. Fix permissions on the parent directory (chmod/chown) or run from the correct project root
  4. Ensure the filesystem is mounted read-write

Example fix

// before
$ ls -l src   # src/templates is a FILE, plan adds src/templates/base.html
// after
$ mv src/templates src.tmplbak && mkdir src/templates
$ plandex apply
Defensive patterns

Strategy: validation

Validate before calling

dir := filepath.Dir(dstPath)
if info, err := os.Stat(dir); err == nil && !info.IsDir() {
  return fmt.Errorf("%s exists as a file; a directory is required", dir)
}
if err := os.MkdirAll(dir, 0o755); err != nil {
  return fmt.Errorf("cannot create %s: %w", dir, err)
}

Type guard

func dirCreatable(dirPath string) bool {
  if info, err := os.Stat(dirPath); err == nil { return info.IsDir() }
  // walk up to find first existing ancestor; it must be a writable dir
  parent := filepath.Dir(dirPath)
  info, err := os.Stat(parent)
  return err == nil && info.IsDir() && info.Mode().Perm()&0o200 != 0
}

Try / catch

if err := os.MkdirAll(filepath.Dir(dstPath), 0o755); err != nil {
  return fmt.Errorf("mkdir %s: %w", filepath.Dir(dstPath), err)
}

Prevention

When it happens

Trigger: os.MkdirAll(filepath.Dir(dstPath), 0755) fails — parent path component is a regular file, permission denied, or filesystem is full/read-only.

Common situations: Plan adds a file under a path where an existing file occupies a directory name (e.g. 'main.go' exists, plan writes 'main.go/util.go'); read-only checkout; disk quota exceeded; writing into a mounted volume without permissions.

Related errors


AI-assisted analysis of plandex-ai/plandex@e2d772072e (2026-09-05). Data as JSON: /api/errors/c4b2eb127cbee7c3. Report an issue: GitHub.