{"record":{"id":"5ad0d751f6c882b2","repo":"jackwener/OpenCLI","slug":"unexpected-result-from-twitter-list-create-json","errorCode":null,"errorMessage":"Unexpected result from twitter list-create: ${JSON.stringify(result)}","messagePattern":"Unexpected result from twitter list-create: (.+?)","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/twitter/list-create.js","lineNumber":42,"sourceCode":"    const modeRaw = String(kwargs.mode || 'public').trim().toLowerCase();\n    if (!name) {\n        throw new ArgumentError('List name is required', 'Example: opencli twitter list-create \"My List\"');\n    }\n    if (name.length > NAME_MAX) {\n        throw new ArgumentError(`List name too long: ${name.length} chars (max ${NAME_MAX})`);\n    }\n    if (description.length > DESCRIPTION_MAX) {\n        throw new ArgumentError(`Description too long: ${description.length} chars (max ${DESCRIPTION_MAX})`);\n    }\n    if (modeRaw !== 'public' && modeRaw !== 'private') {\n        throw new ArgumentError(`Invalid mode: ${JSON.stringify(kwargs.mode)}. Expected \"public\" or \"private\".`);\n    }\n    return { listName: name, listDescription: description, listMode: modeRaw, privateFlag: modeRaw === 'private' };\n}\n\nfunction requireCreateListResult(result, expectedName, expectedMode) {\n    if (!result || typeof result !== 'object') {\n        throw new CommandExecutionError(`Unexpected result from twitter list-create: ${JSON.stringify(result)}`);\n    }\n    if (result.httpStatus === 401 || result.httpStatus === 403) {\n        throw new AuthRequiredError('x.com', `Twitter CreateList returned HTTP ${result.httpStatus}`);\n    }\n    if (!result.ok) {\n        const snippet = String(result.bodyText || '').slice(0, 300);\n        throw new CommandExecutionError(`HTTP ${result.httpStatus} from CreateList: ${snippet}`);\n    }\n    if (!result.bodyJson || typeof result.bodyJson !== 'object') {\n        throw new CommandExecutionError(`CreateList returned malformed JSON payload. Body: ${String(result.bodyText || '').slice(0, 300)}`);\n    }\n    const list = result.bodyJson?.data?.list;\n    if (!list || typeof list !== 'object') {\n        const errors = result.bodyJson?.errors;\n        if (Array.isArray(errors) && errors.length > 0) {\n            throw new CommandExecutionError(`CreateList failed: ${errors[0].message || JSON.stringify(errors[0])}`);\n        }\n        throw new CommandExecutionError(`CreateList returned no list payload. Body: ${String(result.bodyText || '').slice(0, 300)}`);","sourceCodeStart":24,"sourceCodeEnd":60,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/twitter/list-create.js#L24-L60","documentation":"This CommandExecutionError is thrown by requireCreateListResult when the unwrapped browser result is not a non-null object (e.g. null or undefined). It indicates the internal fetch-in-page pipeline failed to return a structured result rather than an HTTP-level problem. The message includes the JSON-stringified value received.","triggerScenarios":"unwrapBrowserResult returning null/undefined because the in-page evaluate failed, was interrupted by navigation, or the browser automation layer returned nothing; passing a wrong-shaped object into buildListCreateRow.","commonSituations":"Browser/page crash or navigation during the fetch; older browser-automation runtime that doesn't serialize the return value; calling buildListCreateRow directly with a mocked/missing result in tests or custom code.","solutions":["Re-run the command; transient page/navigation failures often resolve on retry","Verify the browser session and x.com login are healthy (AuthRequiredError would otherwise be raised for auth issues)","Inspect the browser-automation setup (Playwright/CDP bridge) if it consistently returns null","If calling buildListCreateRow yourself, pass the raw result object from the page.evaluate pipeline"],"exampleFix":"// before\nconst result = undefined;\nconst row = buildListCreateRow({ result, name, description, mode }); // throws\n// after\nconst result = unwrapBrowserResult(await page.evaluate(fetchScript));\nif (!result || typeof result !== 'object') throw new Error('browser returned no result');\nconst row = buildListCreateRow({ result, name, description, mode });","handlingStrategy":"type-guard","validationCode":"const raw = unwrapBrowserResult(await page.evaluate(fetchScript));\nif (raw == null || typeof raw !== 'object') {\n  throw new Error('CreateList pipeline returned no structured result');\n}","typeGuard":"function isCreateListResult(v) {\n  return v != null && typeof v === 'object' &&\n    typeof v.httpStatus === 'number' &&\n    typeof v.ok === 'boolean' &&\n    typeof v.bodyText === 'string';\n}","tryCatchPattern":"try {\n  const rows = await opencli.twitter.listCreate({ name, description, mode });\n} catch (e) {\n  if (e instanceof CommandExecutionError && /Unexpected result from twitter list-create/.test(e.message)) {\n    // transient browser/pipeline failure: log and retry once with a fresh page\n  } else { throw e; }\n}","preventionTips":["Ensure the browser automation runtime serializes evaluate() return values properly","Avoid navigating away from the page while the in-page fetch is in flight","When testing buildListCreateRow directly, always pass a well-formed result object"],"tags":["unexpected-response","browser-automation","internal-error"],"backgroundTag":"unexpected-response-shape","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}