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

  1. Check the actual response body from the configured account endpoint
  2. Fix the connector endpoint to point at the object-shaped account status resource
  3. 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

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


AI-assisted analysis of musistudio/claude-code-router@99f24806c6 (2026-08-27). Data as JSON: /api/errors/c7e8f4cd8174f653. Report an issue: GitHub.