plandex-ai/plandex · error

error marshalling account credentials: %v

Error message

error marshalling account credentials: %v

What it means

After creating the credentials directory, SetAccountCredentials serializes the AccountCredentials struct with json.MarshalIndent. This error wraps marshal failure; credentials cannot be persisted because the struct cannot be converted to JSON (e.g. an unsupported field type such as a channel, func, or cyclic value).

Source

Thrown at app/cli/lib/model_credentials.go:579

	}
	return "❌"
}

var cachedAccountCredentials *types.AccountCredentials

func SetAccountCredentials(creds *types.AccountCredentials) error {
	if auth.Current == nil {
		return fmt.Errorf("no authenticated user")
	}
	dir := filepath.Join(fs.HomePlandexDir, auth.Current.UserId, auth.Current.OrgId)
	err := os.MkdirAll(dir, 0700)
	if err != nil {
		return fmt.Errorf("error creating account credentials directory: %v", err)
	}
	path := filepath.Join(dir, "creds.json")
	bytes, err := json.MarshalIndent(creds, "", "  ")
	if err != nil {
		return fmt.Errorf("error marshalling account credentials: %v", err)
	}
	err = os.WriteFile(path, bytes, 0600)
	if err != nil {
		return fmt.Errorf("error writing account credentials: %v", err)
	}

	cachedAccountCredentials = creds

	return nil
}

func GetAccountCredentials() (*types.AccountCredentials, error) {
	if cachedAccountCredentials != nil {
		return cachedAccountCredentials, nil
	}

	if auth.Current == nil {
		return nil, fmt.Errorf("no authenticated user")

View on GitHub (pinned to e2d772072e)

Solutions

  1. Inspect the wrapped error to find the offending field reported by encoding/json.
  2. Ensure types.AccountCredentials contains only JSON-serializable types; add omitempty or json tags for problematic fields.
  3. Rebuild the CLI against the matching version of the shared types package to rule out version skew.

Example fix

// before
type AccountCredentials struct { TokenCh chan string }
// after
type AccountCredentials struct { AccessToken string `json:"accessToken"` RefreshToken string `json:"refreshToken"` ExpiresAt time.Time `json:"expiresAt"` }
Defensive patterns

Strategy: try-catch

Validate before calling

if _, err := json.Marshal(creds); err != nil {
    return fmt.Errorf("AccountCredentials not serializable: %w", err)
}

Try / catch

if err := SetAccountCredentials(creds); err != nil {
    if strings.Contains(err.Error(), "marshalling account credentials") {
        return fmt.Errorf("credential struct contains a non-JSON field — upgrade/align the shared types package: %w", err)
    }
    return err
}

Prevention

When it happens

Trigger: json.MarshalIndent on *types.AccountCredentials fails — typically only when the struct carries fields not serializable by encoding/json (chan, func, complex) or a custom MarshalJSON returns an error.

Common situations: Rare in practice; usually follows a type change in types.AccountCredentials that introduced a non-JSON-serializable field, or a vendored/shared-type version mismatch after an upgrade.

Understand the failure class

Background: json.Marshal / "failed to marshal" errors in Go: why "unsupported type" happens and how to fix it — this error's family across 22 libraries.

Related errors


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