{"record":{"id":"c81e7d26b943088b","repo":"jackwener/OpenCLI","slug":"mercury-returned-malformed-label","errorCode":null,"errorMessage":"Mercury returned malformed ${label}","messagePattern":"Mercury returned malformed (.+?)","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/mercury/utils.js","lineNumber":109,"sourceCode":"        receipt: parseReceiptPath(kwargs),\n        amount: parseAmount(kwargs),\n        currency: parseCurrency(kwargs),\n        date: parseDate(kwargs),\n        merchant: requireString(kwargs, 'merchant'),\n        category: optionalString(kwargs, 'category', 'Marketing & Advertising'),\n        notes: requireString(kwargs, 'notes'),\n        ocrWaitSeconds: parseOcrWaitSeconds(kwargs),\n        closeAfterReview: optionalBoolean(kwargs, 'close-after-review', false),\n    };\n}\n\nexport function receiptBasename(receipt) {\n    return path.basename(receipt);\n}\n\nexport function assertObject(value, label) {\n    if (!value || typeof value !== 'object' || Array.isArray(value)) {\n        throw new CommandExecutionError(`Mercury returned malformed ${label}`);\n    }\n    return value;\n}\n\nexport function assertMercuryState(value, label = 'page state') {\n    const state = assertObject(value, label);\n    if (typeof state.url !== 'string' || typeof state.title !== 'string') {\n        throw new CommandExecutionError(`Mercury returned malformed ${label}`);\n    }\n    return state;\n}\n\nfunction assertBooleanFields(state, label, fields) {\n    for (const field of fields) {\n        if (typeof state[field] !== 'boolean') {\n            throw new CommandExecutionError(`Mercury returned malformed ${label}: ${field} must be boolean`);\n        }\n    }","sourceCodeStart":91,"sourceCodeEnd":127,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/mercury/utils.js#L91-L127","documentation":"assertObject validates that Mercury (the browser automation backend) returned a non-null, non-array object under the given label. If the value is null/undefined, a primitive, or an array, it throws CommandExecutionError with 'Mercury returned malformed <label>'. This guards the boundary between the CLI and Mercury's JSON responses, which can degrade if the page/extension state is unexpected.","triggerScenarios":"Mercury returns null/undefined where a state object was expected; returns an array instead of an object; a code path returns a string/number (e.g. an error message string) that is fed to assertObject/state.","commonSituations":"Mercury extension not loaded or crashed so the bridge returns null; page navigated away so the snapshot is empty; version mismatch where Mercury returns a differently-shaped payload; network/timeout yielding an error string instead of JSON.","solutions":["Check that the Mercury extension/backend is running and the browser session is alive; restart the browser/Mercury if unsure.","Log the raw value returned for the failing label to see what Mercury actually sent.","Update Mercury/extension and CLI to matching versions so payload shapes align.","Retry the command — transient page-state races often resolve on a fresh run."],"exampleFix":"// before\nconst state = await mercury.getState(); // null when extension unloaded\n// after\nif (!state) throw new Error('Mercury extension not responding; reload extension and retry');\nconst checked = assertObject(state, 'page state');","handlingStrategy":"try-catch","validationCode":"function looksLikeMercuryObject(v) {\n  return !!v && typeof v === 'object' && !Array.isArray(v);\n}","typeGuard":"function isMercuryObject(v) {\n  return typeof v === 'object' && v !== null && !Array.isArray(v);\n}","tryCatchPattern":"try {\n  const state = await inspectMercury(page);\n} catch (e) {\n  if (e instanceof CommandExecutionError && e.message.includes('Mercury returned malformed')) {\n    console.error('Mercury payload unusable; reloading extension/session and retrying once...');\n    await restartMercury();\n    return inspectMercury(page);\n  }\n  throw e;\n}","preventionTips":["Health-check the Mercury extension before running batches","Keep Mercury extension and CLI versions in sync","Retry once on transient malformed payloads","Log raw payloads on failure for diagnosis"],"tags":["runtime","integration","malformed-response","mercury"],"backgroundTag":"malformed-response","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}