plandex-ai/plandex · error
error writing hash file: %v
Error message
error writing hash file: %v
What it means
SaveCustomModelsHash writes the computed hash to <basePath>.hash (e.g. custom-models.json.hash) with os.WriteFile(..., 0644). This error is the OS-level write failure for the hash file; the hash itself was computed successfully. Consequence: custom-models.json may exist without a matching hash, causing subsequent syncs to treat local state as changed.
Source
Thrown at app/cli/lib/custom_models.go:172
err = SaveCustomModelsHash(path, modelsInput)
if err != nil {
return fmt.Errorf("error saving hash file: %v", err)
}
return nil
}
func SaveCustomModelsHash(basePath string, modelsInput *shared.ModelsInput) error {
hashPath := basePath + ".hash"
hash, err := modelsInput.Hash()
if err != nil {
return fmt.Errorf("error hashing models: %v", err)
}
err = os.WriteFile(hashPath, []byte(hash), 0644)
if err != nil {
return fmt.Errorf("error writing hash file: %v", err)
}
return nil
}
func MustSyncCustomModels(path string, serverModelsInput *shared.ModelsInput) bool {
term.StartSpinner("")
jsonData, err := os.ReadFile(path)
if err != nil {
term.OutputErrorAndExit("Error reading custom models file: %v", err)
return false
}
clientModelsInput, err := schema.ValidateModelsInputJSON(jsonData)
if err != nil {
term.StopSpinner()
color.New(color.Bold, term.ColorHiRed).Println("🚨 Error validating custom models file")View on GitHub (pinned to e2d772072e)
Solutions
- Check the wrapped error for 'permission denied' and correct ownership: chown -R $(whoami) ~/.plandex.
- Free disk space if the disk/quota is full.
- Remove a corrupt or root-owned custom-models.json.hash and retry the models command.
- Re-run the custom models write so the JSON file and hash are written together consistently.
Example fix
// before -rw-r--r-- 1 root root custom-models.json.hash # unwritable by user // after sudo rm ~/.plandex/accounts/<userId>/custom-models.json.hash plandex models # rewrites hash as current user
Defensive patterns
Strategy: try-catch
Validate before calling
// Ensure the hash file location is writable before syncing
hp := path + ".hash"
if f, err := os.OpenFile(hp, os.O_WRONLY|os.O_CREATE, 0644); err != nil {
// abort: hash file not writable
} else {
f.Close()
} Type guard
func isHashWriteError(err error) bool {
return err != nil && strings.Contains(err.Error(), "error writing hash file")
} Try / catch
if err := lib.WriteCustomModelsFile(path, input); err != nil {
if isHashWriteError(err) {
term.Error("Hash file write failed; delete " + path + ".hash and retry")
return
}
return err
} Prevention
- Ensure the owning user matches the user running the CLI (avoid sudo).
- Check quota/disk space before large model-pack updates.
- If a hash write fails, delete the .hash file so sync doesn't compare against stale data.
- Keep ~/.plandex on a local, non-read-only filesystem.
When it happens
Trigger: os.WriteFile failing on the hash path because the directory is missing, permissions deny writing, or disk is full — same conditions as the JSON write but specifically on the .hash file.
Common situations: Read-only filesystem; quota exceeded; .hash file owned by root after sudo usage; accounts directory manually cleaned while file handle expectations remain.
Understand the failure class
Background: "Permission denied" / "Failed to write" file errors: why a library can't write its files to disk (EACCES, EPERM, ENOSPC) and how to fix them — this error's family across 43 libraries.
Related errors
- failed to write %s: %s
- error writing file: %v
- error writing JSON file: %v
- error writing hash file: %v
- error walking directory: %s
AI-assisted analysis of plandex-ai/plandex@e2d772072e (2026-09-05).
Data as JSON: /api/errors/fee80efea20ab0f7.
Report an issue: GitHub.