{"record":{"id":"eb4b8a775298a21f","repo":"jackwener/OpenCLI","slug":"context-returned-a-malformed-message-eb4b8a","errorCode":null,"errorMessage":"${context} returned a malformed message.","messagePattern":"(.+?) returned a malformed message\\.","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/twitter/reply.js","lineNumber":37,"sourceCode":"    // (silent: matched `/status/1234567` on substring `/status/123` and\n    // accepted any host). parseTweetUrl bubbles ArgumentError on\n    // malformed/off-domain inputs.\n    const target = parseTweetUrl(rawUrl);\n    return `https://x.com/compose/post?in_reply_to=${target.id}`;\n}\n\nfunction isPromiseCollectedError(err) {\n    const msg = err instanceof Error ? err.message : String(err);\n    return msg.includes('Promise was collected');\n}\n\nfunction requireReplyActionResult(value, context) {\n    const result = unwrapBrowserResult(value);\n    if (!result || typeof result !== 'object' || Array.isArray(result) || typeof result.ok !== 'boolean') {\n        throw new CommandExecutionError(`${context} returned a malformed result.`);\n    }\n    if (Object.prototype.hasOwnProperty.call(result, 'message') && result.message != null && typeof result.message !== 'string') {\n        throw new CommandExecutionError(`${context} returned a malformed message.`);\n    }\n    if (Object.prototype.hasOwnProperty.call(result, 'url') && result.url != null && typeof result.url !== 'string') {\n        throw new CommandExecutionError(`${context} returned a malformed status url.`);\n    }\n    return result;\n}\n\nfunction validateReplyStatusUrl(result) {\n    if (!result.url) return;\n    let url;\n    try {\n        url = new URL(result.url);\n    } catch {\n        throw new CommandExecutionError('Twitter reply completion returned a malformed status url.');\n    }\n    const hostname = url.hostname.toLowerCase().replace(/^www\\./, '');\n    const match = url.pathname.match(/^\\/([^/]+)\\/status\\/(\\d+)\\/?$/);\n    if (!['x.com', 'twitter.com', 'mobile.twitter.com'].includes(hostname) || !match) {","sourceCodeStart":19,"sourceCodeEnd":55,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/twitter/reply.js#L19-L55","documentation":"requireReplyActionResult validates the object returned from page.evaluate() in the twitter reply flow before it is used. A browser-side result may include a `message` field for error reporting; the library throws this CommandExecutionError when `message` is present and non-null but is not a string (e.g. a number, object, or array). This protects callers from passing a non-string message into error construction or templating, which would produce broken diagnostics.","triggerScenarios":"The in-page script (reply click, reply text insertion, or submit polling) returns { ok, message: <non-string> } — e.g. `message: e` (an Error object) or `message: errorCode` (a number) instead of `message: e.toString()` / a string literal.","commonSituations":"Editing or writing a new page.evaluate() snippet inside clis/twitter/reply.js and forgetting to stringify the caught exception; a code change swapping a string message for a structured { code, text } object; serialization quirks where a string becomes a String wrapper object.","solutions":["Fix the browser-side script to return a string: replace `return { ok: false, message: e }` with `return { ok: false, message: e instanceof Error ? e.message : String(e) }`.","Check that the evaluate snippet's return object only puts strings into `message`; move structured error data to separate fields.","If you control the caller, coerce before returning: `message: String(rawMessage)`."],"exampleFix":"// before (inside page.evaluate)\ncatch (e) {\n  return { ok: false, message: e };\n}\n// after\ncatch (e) {\n  return { ok: false, message: e instanceof Error ? e.message : String(e) };\n}","handlingStrategy":"type-guard","validationCode":"// After receiving any browser result, before using .message:\nif (result.message != null && typeof result.message !== 'string') {\n  throw new Error('message field must be a string');\n}","typeGuard":"function isReplyActionResult(v) {\n  return !!v && typeof v === 'object' && !Array.isArray(v) &&\n    typeof v.ok === 'boolean' &&\n    (v.message == null || typeof v.message === 'string');\n}","tryCatchPattern":"try {\n  await cli('twitter', 'reply', { url, text });\n} catch (e) {\n  if (String(e.message).includes('returned a malformed message')) {\n    // treat as a tooling/bridge bug: log the raw result and report\n  } else throw e;\n}","preventionTips":["Always stringify caught exceptions in page.evaluate snippets: message: e instanceof Error ? e.message : String(e).","Keep message fields string-only; move structured data to sibling fields.","Add a unit test asserting evaluate results pass isReplyActionResult."],"tags":["browser-automation","type-validation","twitter"],"backgroundTag":"schema-validation-failed","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}