{"record":{"id":"a4c96d2bf717205b","repo":"paperclipai/paperclip","slug":"could-not-load-wireframe-viewer-styles-a4c96d","errorCode":null,"errorMessage":"Could not load wireframe viewer styles","messagePattern":"Could not load wireframe viewer styles","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"doc/plans/chat-adapters/generate-wireframes-v8.mjs","lineNumber":931,"sourceCode":"        `### ${screen.id} · ${screen.title}\\n\\nPurpose: ${screen.subtitle}\\n\\n${screen.annotations.map((item, index) => `${index + 1}. ${item}`).join(\"\\n\")}\\n\\n${screen.actions ? `Actions:\\n\\n${screen.actions.map(([label, effect]) => `- **${label}:** ${effect}`).join(\"\\n\")}\\n\\n` : \"\"}Rationale: ${screen.rationale}`,\n    )\n    .join(\"\\n\\n\");\n  const permissions = permissionModel\n    .map(([name, behavior]) => `- **${name}:** ${behavior}`)\n    .join(\"\\n\");\n  return `# Paperclip Chat Adapters UI Surfaces — v8\\n\\nDate: 2026-09-04  \\nOriginal planning base: \\`${baseSha}\\`; release qualification records the exact tested revision separately.  \\nReview viewer: [\\`index.html\\`](./index.html)  \\nWireframes: [\\`wireframes-v8/\\`](./wireframes-v8/)\\n\\n## Permission model\\n\\n${permissions}\\n\\n## Access tab\\n\\n**Settings answers where the bot may work. Access answers who an external sender represents and what Paperclip authority applies.** A linked external identity acts as its mapped Paperclip user and is checked against current permissions on every action. An unlinked identity may be allowed under the fixed restricted profile: it can converse within enabled resources and attach safe files, but it cannot approve, change budgets, hire, manage permissions or connections, or reassign agents. The connection owner remains an internal audit and authority ceiling; it is not ordinary UI configuration.\\n\\n## Conversations tab\\n\\nEach provider has one plain list. Every row contains the external conversation, Paperclip task, current state, an Open-provider link, and Open task. There is no separate binding-management section or conversation-boundary explainer. If provider access disappears, the row becomes unavailable while its history remains inspectable.\\n\\nThe former \\\"How conversations work\\\" screens are removed. Provider-native activation and reply behavior remains implementation documentation, not a standalone product page.\\n\\n## Screen inventory\\n\\n| ID | Group | Surface | Title | Desktop | Mobile |\\n|---|---|---|---|---|---|\\n${inventory}\\n\\n## Annotation and action notes\\n\\n${details}\\n`;\n}\n\nfunction viewerHtml() {\n  const template = readFileSync(\n    join(\n      root,\n      \"../../../packages/skills-catalog/catalog/bundled/product/wireframe/assets/site-template.html\",\n    ),\n    \"utf8\",\n  );\n  const style = template.match(/<style>[\\s\\S]*?<\\/style>/)?.[0];\n  if (!style) throw new Error(\"Could not load wireframe viewer styles\");\n  const toc = groups\n    .map(\n      ([label, screens]) =>\n        `<h2>${esc(label)}</h2>${screens.map((screen) => `<a href=\"#s${screen.id}\"><span class=\"num\">${Number(screen.id)}</span>${esc(screen.title)}</a>`).join(\"\\n\")}`,\n    )\n    .join(\"\\n\");\n  const sections = groups\n    .map(\n      ([label, screens]) =>\n        `<div class=\"provider-break\"><div class=\"lede\">${esc(label)}</div><h2>${label === \"Start\" ? \"Shared connection start\" : label === \"Paperclip\" ? \"Shared Paperclip surfaces\" : `${esc(label)} connector`}</h2></div>${screens\n          .map((screen) => {\n            const notes = screen.annotations\n              .map(\n                (note, index) => `<li><b>${index + 1}</b> — ${esc(note)}</li>`,\n              )\n              .join(\"\\n\");\n            const actions = screen.actions\n              ? `<h3>What the actions do</h3><ul>${screen.actions.map(([name, effect]) => `<li><b>${esc(name)}</b> — ${esc(effect)}</li>`).join(\"\\n\")}</ul>`","sourceCodeStart":913,"sourceCodeEnd":949,"githubUrl":"https://github.com/paperclipai/paperclip/blob/3f1d897a7c018d76563a21c6e39c3c9b03933622/doc/plans/chat-adapters/generate-wireframes-v8.mjs#L913-L949","documentation":"Fail-fast guard in the v8 wireframe generator: the script cannot extract the viewer CSS block from the HTML template it is assembling the standalone wireframe viewer around, so it aborts instead of emitting a viewer with missing/unstyled presentation. Fires when the template file at the configured path is missing, unreadable, or no longer contains the style markers the generator scrapes.","triggerScenarios":"Thrown at doc/plans/chat-adapters/generate-wireframes-v8.mjs:931 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Verify the template path passed to the generator exists and is readable.","Re-add or update the expected style markers in the template after hand-editing the viewer HTML.","Regenerate the template from the version the generator was written against (check git history of the plan file).","If the template was intentionally restructured, update the style-extraction logic in the generator to match the new markers."],"exampleFix":null,"handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"3f1d897a7c018d76563a21c6e39c3c9b03933622","analyzedAt":"2026-09-18T08:03:59.046Z","contentChangedAt":"2026-09-18T08:03:59.046Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}