musistudio/claude-code-router · error · Error
Account endpoint returned a non-object payload.
Error message
Account endpoint returned a non-object payload.
What it means
normalizeRemoteSnapshot validates that the account endpoint payload is a JSON object (isRecord). When the remote account endpoint returns a JSON array, string, number, or null, this error is thrown instead of processing meters/errors.
Source
Thrown at packages/core/src/providers/account-service.ts:950
credentialLabel: credential?.name ?? credential?.label ?? credential?.id,
errors: errors.length > 0 ? errors : undefined,
message,
meters,
nextRefreshAt: new Date(now.getTime() + refreshIntervalMs).toISOString(),
provider,
source,
status,
updatedAt: now.toISOString()
};
}
function normalizeRemoteSnapshot(
provider: string,
payload: unknown,
source: ProviderAccountConnectorSource
): ProviderAccountSnapshot {
if (!isRecord(payload)) {
throw new Error("Account endpoint returned a non-object payload.");
}
const meters = Array.isArray(payload.meters)
? payload.meters.map((meter) => normalizeMeter(meter, source)).filter((meter): meter is ProviderAccountMeter => Boolean(meter))
: [];
return {
errors: normalizeRemoteErrors(payload.errors, source),
message: readString(payload.message),
meters,
nextRefreshAt: readString(payload.nextRefreshAt),
provider: readString(payload.provider) || provider,
source,
status: normalizeStatus(readString(payload.status)) ?? statusFromMeters(meters, [], 1),
updatedAt: readString(payload.updatedAt) || new Date().toISOString()
};
}
function grokSubscriptionMeters(payload: unknown, source: ProviderAccountConnectorSource = "http-json"): ProviderAccountMeter[] {
const allowAccess = grokSubscriptionBoolean(payload, [View on GitHub (pinned to 99f24806c6)
Solutions
- Check the actual response body from the configured account endpoint
- Fix the connector endpoint to point at the object-shaped account status resource
- If the provider API changed, update the connector/manifest mapping
Defensive patterns
Strategy: try-catch
Type guard
const isRecord = (v: unknown): v is Record<string, unknown> => typeof v === 'object' && v !== null && !Array.isArray(v);
Try / catch
catch (e) { if (e.message.includes('non-object payload')) logRawBodyAndEndpoint(); else throw e; } Prevention
- Monitor provider API changelogs
- Log raw account endpoint responses during integration
When it happens
Trigger: Any provider account snapshot fetch whose HTTP JSON body parses to a non-object (e.g. an array of meters, or a plain string).
Common situations: Provider changed its account/status API shape; misconfigured endpoint URL pointing to a list resource; proxy or captive portal returning unexpected JSON.
Related errors
- The CCR artifact endpoint returned a non-media content type.
- The CCR media artifact exceeds the inline preview size limit
- Compressed CCR media artifacts are not accepted for inline p
- The CCR artifact response was empty.
- The CCR artifact response length did not match its headers.
AI-assisted analysis of musistudio/claude-code-router@99f24806c6 (2026-08-27).
Data as JSON: /api/errors/c7e8f4cd8174f653.
Report an issue: GitHub.