{"record":{"id":"7fb798d132a10497","repo":"jackwener/OpenCLI","slug":"context-returned-a-malformed-status-url","errorCode":null,"errorMessage":"${context} returned a malformed status url.","messagePattern":"(.+?) returned a malformed status url\\.","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/twitter/reply.js","lineNumber":40,"sourceCode":"    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) {\n        throw new CommandExecutionError('Twitter reply completion returned a malformed status url.');\n    }\n}","sourceCodeStart":22,"sourceCodeEnd":58,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/twitter/reply.js#L22-L58","documentation":"requireReplyActionResult additionally validates the `url` field of the browser-evaluate result for the reply flow. If the in-page script reports a status URL (`url`) that is present and non-null but not a string, the library throws this CommandExecutionError instead of letting a non-string propagate into URL parsing. It is a defensive contract check on the browser bridge data.","triggerScenarios":"A page.evaluate() snippet in the reply flow returns { ok: true, url: <non-string> } — e.g. `url: location` (a Location object), `url: tweetId` (a number), or a URL built as an object rather than a string.","commonSituations":"Hand-edited evaluate snippets returning `url: new URL(...)` instead of `.href`; automation wrapping the href in a DOM node; refactors where the tweet permalink became a structured object { pathname, id }.","solutions":["Return a string from the page script: `url: location.href` or `url: anchor.href` rather than the object.","Coerce before returning: `url: String(rawUrl)`.","Verify the evaluate snippet only sets `url` when it has a string permalink matching /status/<id>."],"exampleFix":"// before\nreturn { ok: true, url: new URL(permalink) };\n// after\nreturn { ok: true, url: permalink.href };","handlingStrategy":"type-guard","validationCode":"if (result.url != null && typeof result.url !== 'string') {\n  throw new Error('url field must be a string');\n}","typeGuard":"function hasStringUrl(v) {\n  return v == null || typeof v !== 'object' || v.url == null || typeof v.url === 'string';\n}","tryCatchPattern":"try {\n  await cli('twitter', 'reply', { url, text });\n} catch (e) {\n  if (String(e.message).includes('malformed status url') && !(e instanceof TypeError) === false || String(e.message).includes('returned a malformed status url')) {\n    // non-string url from bridge: log raw result, do not retry blindly\n  } else throw e;\n}","preventionTips":["Return href strings (element.href, location.href), never URL/Location objects, from page.evaluate.","Coerce with String(rawUrl) at the boundary inside the page script.","Review any modified evaluate snippet for object-valued url fields before merging."],"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"}