plandex-ai/plandex · error
error unmarshalling JSON file: %v
Error message
error unmarshalling JSON file: %v
What it means
After reading the local custom-models JSON, CustomModelsCheckLocalChanges unmarshals it into shared.ClientModelsInput; a parse failure is wrapped as 'error unmarshalling JSON file: %v'. This means the file exists and is readable but its content is not valid JSON of the expected shape.
Source
Thrown at app/cli/lib/custom_models.go:113
exists, err := fs.FileExists(path)
if err != nil {
return CustomModelsCheckLocalChangesResult{}, err
}
if !exists {
return CustomModelsCheckLocalChangesResult{}, nil
}
localJsonData, err := os.ReadFile(path)
if err != nil {
return CustomModelsCheckLocalChangesResult{}, fmt.Errorf("error reading JSON file: %v", err)
}
var localClientModelsInput shared.ClientModelsInput
err = json.Unmarshal(localJsonData, &localClientModelsInput)
if err != nil {
return CustomModelsCheckLocalChangesResult{}, fmt.Errorf("error unmarshalling JSON file: %v", err)
}
localModelsInput := localClientModelsInput.ToModelsInput()
lastSavedHash, err := os.ReadFile(hashPath)
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,View on GitHub (pinned to e2d772072e)
Solutions
- Validate the JSON with a linter/parser and fix syntax errors
- Delete or rename the file and rerun the custom-models sync to regenerate it
- If it appeared after an upgrade, let the sync rewrite the file in the new schema
- Compare the file against the expected ClientModelsInput structure for type mismatches
Example fix
// before: hard failure on malformed cache file
err = json.Unmarshal(localJsonData, &localClientModelsInput)
if err != nil {
return CustomModelsCheckLocalChangesResult{}, fmt.Errorf("error unmarshalling JSON file: %v", err)
}
// after: caller resets corrupted cache
if json.Valid(localJsonData) == false {
os.Remove(path) // force resync
} Defensive patterns
Strategy: validation
Validate before calling
data, err := os.ReadFile(path)
if err == nil && !json.Valid(data) {
os.Remove(path) // corrupted cache; force regeneration
} Type guard
func validClientModelsInput(data []byte) bool {
var in shared.ClientModelsInput
return json.Unmarshal(data, &in) == nil
} Try / catch
res, err := CustomModelsCheckLocalChanges(...)
if err != nil && strings.Contains(err.Error(), "error unmarshalling JSON file") {
os.Rename(path, path+".bak") // preserve for inspection, then resync
return SyncCustomModels()
} Prevention
- Write the JSON atomically (temp file + rename) to prevent truncation
- Validate JSON after manual edits before running the CLI
- Migrate/reset the file when upgrading across schema versions
When it happens
Trigger: json.Unmarshal(localJsonData, &localClientModelsInput) fails — truncated write, manual edit introduced invalid JSON, schema drift (fields changed type/shape across app versions), or empty/corrupted file.
Common situations: User hand-edited custom-models.json and broke the syntax; crash/interrupt during a previous write left a truncated file; upgrading the CLI changed the ClientModelsInput schema so old files no longer decode.
Understand the failure class
Background: "failed to unmarshal" / json.Unmarshal errors: why parsing a response into a Go struct fails and how to fix it — this error's family across 23 libraries.
Related errors
- error parsing embedded schema %s: %v
- error parsing schema JSON: %v
- refresh failed - decode: %w
- error reading JSON file: %v
- error marshalling models: %v
AI-assisted analysis of plandex-ai/plandex@e2d772072e (2026-09-05).
Data as JSON: /api/errors/7ddd4d861d5ee293.
Report an issue: GitHub.