plandex-ai/plandex · error
error creating directory: %v
Error message
error creating directory: %v
What it means
WriteCustomModelsFile creates the parent directory of the target custom-models JSON with os.MkdirAll(..., 0755) before writing; a directory-creation failure is wrapped as 'error creating directory: %v'.
Source
Thrown at app/cli/lib/custom_models.go:138
if err != nil && !os.IsNotExist(err) {
return CustomModelsCheckLocalChangesResult{}, fmt.Errorf("error reading hash file: %v", err)
}
currentHash, err := localModelsInput.Hash()
if err != nil {
return CustomModelsCheckLocalChangesResult{}, fmt.Errorf("error hashing models: %v", err)
}
return CustomModelsCheckLocalChangesResult{
HasLocalChanges: currentHash != string(lastSavedHash),
LocalModelsInput: localModelsInput,
}, nil
}
func WriteCustomModelsFile(path string, modelsInput *shared.ModelsInput) error {
err := os.MkdirAll(filepath.Dir(path), 0755)
if err != nil {
return fmt.Errorf("error creating directory: %v", err)
}
clientModelsInput := modelsInput.ToClientModelsInput()
clientModelsInput.PrepareUpdate()
jsonData, err := json.MarshalIndent(clientModelsInput, "", " ")
if err != nil {
return fmt.Errorf("error marshalling models: %v", err)
}
err = os.WriteFile(path, jsonData, 0644)
if err != nil {
return fmt.Errorf("error writing file: %v", err)
}
err = SaveCustomModelsHash(path, modelsInput)
if err != nil {
return fmt.Errorf("error saving hash file: %v", err)View on GitHub (pinned to e2d772072e)
Solutions
- Check the wrapped OS error (%v) for the exact mkdir failure
- Verify filepath.Dir(path) is writable and no file occupies a directory component of the path
- Fix permissions (chmod/chown) or free disk space if that is the cause
- Correct HOME/config-path configuration so the directory lands somewhere writable
Example fix
// before
err := os.MkdirAll(filepath.Dir(path), 0755)
if err != nil {
return fmt.Errorf("error creating directory: %v", err)
}
// after: caller preflight
if info, err := os.Stat(filepath.Dir(path)); err == nil && !info.IsDir() {
os.Remove(filepath.Dir(path)) // file blocking directory creation
} Defensive patterns
Strategy: validation
Validate before calling
dir := filepath.Dir(path)
if info, err := os.Stat(dir); err == nil && !info.IsDir() {
return fmt.Errorf("%s exists and is not a directory", dir)
}
if err := syscall.Access(dir, syscall.O_RDWR); err != nil {
return fmt.Errorf("directory not writable: %s", dir)
} Type guard
func dirWritable(path string) bool {
info, err := os.Stat(path)
if err != nil || !info.IsDir() {
return false
}
return info.Mode().Perm()&0200 != 0
} Try / catch
err := WriteCustomModelsFile(path, modelsInput)
if err != nil && strings.Contains(err.Error(), "error creating directory") {
fmt.Fprintf(os.Stderr, "cannot create %s — check permissions/disk: %v\n", filepath.Dir(path), err)
os.Exit(1)
} Prevention
- Ensure the state directory path is not occupied by a regular file
- Verify the parent directory is writable (check HOME/config path config)
- Monitor disk space and mount flags (read-only) in CI/container environments
When it happens
Trigger: os.MkdirAll(filepath.Dir(path), 0755) fails — parent path component is a file, permission denied, read-only filesystem, or invalid path characters.
Common situations: Config directory path exists as a regular file; HOME misconfigured to a non-writable location; disk full or mounted read-only; sandboxed/containerized environments with restricted filesystem writes.
Related errors
- error checking if settings-v2.json exists: %v
- error reading JSON file: %v
- error reading hash file: %v
- error writing file: %v
- error checking if current-plans-v2.json exists: %v
AI-assisted analysis of plandex-ai/plandex@e2d772072e (2026-09-05).
Data as JSON: /api/errors/6b4ebd002d00743e.
Report an issue: GitHub.