musistudio/claude-code-router · error · Error
Chrome login import payload must be an object.
Error message
Chrome login import payload must be an object.
What it means
The IPC/HTTP import payload handler validates that the incoming JSON body is a plain object before reading cookies/localStorage arrays. Any non-object JSON (array, string, number, null, or malformed structure) is rejected early rather than crashing deeper in the import pipeline.
Source
Thrown at packages/electron/src/main/chrome-login-import.ts:441
return `${secure ? "https" : "http"}://${host}${normalizedPath}`;
}
function cookieDomainMatches(cookieHost: string, allowedDomain: string): boolean {
return cookieHost === allowedDomain || cookieHost.endsWith(`.${allowedDomain}`);
}
function normalizeSameSite(value: unknown): CookieSetDetails["sameSite"] | undefined {
return value === "lax" || value === "strict" || value === "no_restriction" || value === "unspecified"
? value
: undefined;
}
function readImportPayload(payload: unknown): {
cookies: ChromeLoginImportCookie[];
localStorage: ChromeLoginImportLocalStorage[];
} {
if (!isRecord(payload)) {
throw new Error("Chrome login import payload must be an object.");
}
const cookies = Array.isArray(payload.cookies)
? payload.cookies.filter(isRecord) as ChromeLoginImportCookie[]
: [];
const localStorage = Array.isArray(payload.localStorage)
? payload.localStorage.filter(isRecord) as ChromeLoginImportLocalStorage[]
: [];
if (cookies.length === 0 && localStorage.length === 0) {
throw new Error("Chrome login import payload must include cookies or localStorage.");
}
return { cookies, localStorage };
}
function cloneJob(job: StoredChromeLoginImportJob): ChromeLoginImportJob {
return {
...job,
domains: [...job.domains],
...(job.resultView on GitHub (pinned to 99f24806c6)
Solutions
- Ensure the request body is a JSON object: { "cookies": [...], "localStorage": [...] }
- If JSON may be double-encoded, JSON.parse once before sending
- Log the parsed typeof in a wrapper to catch serializer bugs
Example fix
// before
await post(JSON.stringify(JSON.stringify(payload)));
// after
await post(JSON.stringify({ cookies: payload.cookies ?? [], localStorage: payload.localStorage ?? [] })); Defensive patterns
Strategy: type-guard
Validate before calling
if (typeof payload !== 'object' || payload === null || Array.isArray(payload)) {
throw new TypeError('Import payload must be a JSON object');
} Type guard
function isImportPayloadObject(value: unknown): value is Record<string, unknown> {
return typeof value === 'object' && value !== null && !Array.isArray(value);
} Try / catch
try { await importPayload(raw); } catch (e) { if (e instanceof Error && e.message === 'Chrome login import payload must be an object.') { /* fix serializer, resend */ } else throw e; } Prevention
- Type the sender side against a payload interface
- Beware double JSON.stringify producing a top-level string
- Validate shape client-side before POSTing
When it happens
Trigger: POSTing a JSON body like "[...]", "null", or "\"text\"" to the import endpoint; a serializer bug on the exporter side emitting a top-level array or primitive.
Common situations: Client serializes with JSON.stringify on the wrong variable; double-encoded JSON (a JSON string of JSON); hand-crafted curl payloads missing the outer braces.
Related errors
- Provider payload must be a JSON object.
- Provider manifest must be a JSON object.
- Sample must be a JSON object with an object body
- Sample headers must be a JSON object containing string or st
- ZCode profiles can only open the app; agent arguments are no
AI-assisted analysis of musistudio/claude-code-router@99f24806c6 (2026-08-27).
Data as JSON: /api/errors/0075ce39cb884cb9.
Report an issue: GitHub.