{"record":{"id":"6370d24cd477e527","repo":"jackwener/OpenCLI","slug":"unexpected-code-payload-shape-codeurl","errorCode":null,"errorMessage":"Unexpected code payload shape: ${codeUrl}","messagePattern":"Unexpected code payload shape: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"clis/uiverse/_shared.js","lineNumber":113,"sourceCode":"    routeData = await fetchJsonInBrowser(page, routeUrl);\n  }\n\n  if (!routeData?.post?.id) {\n    throw new Error(`Could not resolve post.id from the component page: ${normalized.url}`);\n  }\n\n  return {\n    ...normalized,\n    post: routeData.post,\n    routeData,\n  };\n}\n\nexport async function getRawCode(page, postId) {\n  const codeUrl = `${UIVERSE_BASE_URL}/resource/post/code/${postId}?v=1&_data=${encodeURIComponent(CODE_DATA_KEY)}`;\n  const payload = await fetchJsonInBrowser(page, codeUrl);\n  if (typeof payload?.html !== 'string' || typeof payload?.css !== 'string') {\n    throw new Error(`Unexpected code payload shape: ${codeUrl}`);\n  }\n  return payload;\n}\n\nexport function inferLanguage(target, post) {\n  if (target === 'react') return 'tsx';\n  if (target === 'vue') return 'vue';\n  if (target === 'html') return post?.isTailwind ? 'html+tailwind' : 'html';\n  if (target === 'css') return 'css';\n  return 'text';\n}\n\nexport function getCodeLength(code) {\n  return String(code || '').length;\n}\n\nfunction normalizeExportTarget(target) {\n  return String(target || '').trim().toLowerCase() === 'vue' ? 'Vue' : 'React';","sourceCodeStart":95,"sourceCodeEnd":131,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/uiverse/_shared.js#L95-L131","documentation":"Thrown by getRawCode when the /resource/post/code/<postId> endpoint returns a 200 JSON payload that lacks string-typed html and css fields. The library expects { html, css } (and possibly more) and treats any other shape as unusable for generating exports.","triggerScenarios":"Uiverse changed the code-resource loader response shape (e.g. renamed html/css keys or nested them); the postId is valid but the component has no stored code (empty strings are fine, but null/missing is not); the endpoint returned a generic Remix error JSON ({ message: ... }) with 200; component saved with Tailwind-only or an alternate code representation.","commonSituations":"Scraping right after a uiverse.io backend migration; components created with newer formats the endpoint represents differently; requesting a code resource for a deleted or private post whose endpoint returns an error object instead of failing the request.","solutions":["Log the payload to see the actual shape returned for that postId","If keys changed, update getRawCode in clis/uiverse/_shared.js to match the new response schema","Re-fetch post details to ensure you are using a fresh post.id (a stale id may yield an error-shaped payload)","Test the same codeUrl manually in the logged-in browser to compare responses"],"exampleFix":"// before\nconst payload = await getRawCode(page, postId); // throws 'Unexpected code payload shape'\n// after\ntry {\n  var payload = await getRawCode(page, postId);\n} catch (e) {\n  console.error(e.message, '— inspect', `https://uiverse.io/resource/post/code/${postId}?v=1&_data=routes/resource.post.code.$id`);\n  throw e;\n}","handlingStrategy":"type-guard","validationCode":"const payload = await fetchJsonInBrowser(page, codeUrl);\nconst isCodePayload = (p) => typeof p?.html === 'string' && typeof p?.css === 'string';\nif (!isCodePayload(payload)) {\n  console.error('Unexpected payload keys:', Object.keys(payload || {}));\n  throw new Error('code endpoint schema changed');\n}","typeGuard":"const hasCodeShape = (p) =>\n  p !== null && typeof p === 'object' && typeof p.html === 'string' && typeof p.css === 'string';","tryCatchPattern":"try {\n  const code = await getRawCode(page, postId);\n} catch (e) {\n  if (e.message.startsWith('Unexpected code payload shape')) {\n    console.error(`Schema drift for postId ${postId}; skipping.`);\n    return null; // or re-fetch details for a fresh postId\n  }\n  throw e;\n}","preventionTips":["Log Object.keys(payload) on failure to spot renamed fields immediately","Keep a fresh post.id — stale/deleted posts can yield error-shaped payloads","Pin tests against a known-good component so schema drift is caught early","Check uiverse.io changelog/behavior after any site update before bulk runs"],"tags":["schema-validation","scraping","site-change"],"backgroundTag":"schema-validation-failed","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}