plandex-ai/plandex · error
error unmarshalling accounts.json: %v
Error message
error unmarshalling accounts.json: %v
What it means
loadAccounts successfully read accounts.json but json.Unmarshal could not parse its contents into []*shared.ClientAccount. This means the local accounts store is malformed — corrupt, truncated, hand-edited, or written by an incompatible CLI version with a schema change.
Source
Thrown at app/cli/auth/state.go:30
var Current *shared.ClientAuth
func loadAccounts() ([]*shared.ClientAccount, error) {
bytes, err := os.ReadFile(fs.HomeAccountsPath)
if err != nil {
if os.IsNotExist(err) {
// no accounts
return []*shared.ClientAccount{}, nil
} else {
return nil, fmt.Errorf("error reading accounts.json: %v", err)
}
}
var accounts []*shared.ClientAccount
err = json.Unmarshal(bytes, &accounts)
if err != nil {
return nil, fmt.Errorf("error unmarshalling accounts.json: %v", err)
}
return accounts, nil
}
func setAuth(auth *shared.ClientAuth) error {
err := storeAccount(&auth.ClientAccount)
if err != nil {
return fmt.Errorf("error storing account: %v", err)
}
Current = auth
err = writeCurrentAuth()
if err != nil {
return fmt.Errorf("error writing auth: %v", err)View on GitHub (pinned to e2d772072e)
Solutions
- Inspect ~/.plandex/accounts.json and fix or remove the invalid JSON
- Back it up, then delete it — the CLI recreates it on next sign-in (you'll need to sign in again)
- Validate the JSON with a linter (jq . accounts.json) before restoring
- Ensure CLI version matches the file's schema; don't hand-edit the store
Example fix
// before
$ cat ~/.plandex/accounts.json
{"id": ...} # object, not array
error unmarshalling accounts.json: json: cannot unmarshal object into Go value of type []*shared.ClientAccount
// after
$ mv ~/.plandex/accounts.json ~/.plandex/accounts.json.bak
$ plandex-cli sign-in # recreates valid accounts.json Defensive patterns
Strategy: validation
Validate before calling
// validate accounts.json parses before auth flows touch it
bytes, err := os.ReadFile(fs.HomeAccountsPath)
if err == nil {
var accounts []*shared.ClientAccount
if err := json.Unmarshal(bytes, &accounts); err != nil {
return fmt.Errorf("accounts.json corrupt, back it up and re-sign-in: %v", err)
}
} Type guard
func validAccountsJSON(path string) bool {
b, err := os.ReadFile(path)
if err != nil { return false }
var accounts []*shared.ClientAccount
return json.Unmarshal(b, &accounts) == nil
} Try / catch
accounts, err := loadAccounts()
if err != nil {
if strings.Contains(err.Error(), "error unmarshalling accounts.json") {
// back up the corrupt file, delete it, and re-authenticate
os.Rename(fs.HomeAccountsPath, fs.HomeAccountsPath+".bak")
}
return err
} Prevention
- Never hand-edit accounts.json
- Back up the file before CLI upgrades/downgrades (schema changes)
- Run jq . ~/.plandex/accounts.json to validate after a crash
- Ensure writes complete (avoid killing the CLI mid-save / full disk)
When it happens
Trigger: json.Unmarshal(bytes, &accounts) fails on the contents of fs.HomeAccountsPath: invalid JSON syntax, wrong top-level type (e.g. an object instead of an array), or fields that don't match shared.ClientAccount.
Common situations: File truncated by a crash or full disk mid-write; manual editing that broke JSON; downgrading/upgrading the CLI across a schema change; a stray non-JSON file placed at ~/.plandex/accounts.json.
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 loading accounts: %v
- error unmarshalling current-plans-v2.json: %v
- unmarshal error: %w
- error unmarshalling convo file: %v
- error unmarshalling convo message: %v
AI-assisted analysis of plandex-ai/plandex@e2d772072e (2026-09-05).
Data as JSON: /api/errors/a6331efa1da301af.
Report an issue: GitHub.