{"record":{"id":"85929ef594eae690","repo":"pbakaus/impeccable","slug":"live-browser-script-part-missing-part-name","errorCode":null,"errorMessage":"Live browser script part missing: ${part.name} (${part.path})","messagePattern":"Live browser script part missing: (.+?) \\((.+?)\\)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"critical","filePath":"plugin/skills/impeccable/scripts/live/browser-script-parts.mjs","lineNumber":24,"sourceCode":"export const LIVE_BROWSER_SCRIPT_PARTS = Object.freeze([\n  Object.freeze({ name: 'session-state', file: 'live-browser-session.js' }),\n  Object.freeze({ name: 'dom-helpers', file: 'live-browser-dom.js' }),\n  Object.freeze({ name: 'browser-ui', file: 'live-browser.js' }),\n]);\n\nexport function resolveLiveBrowserScriptParts(scriptsDir, parts = LIVE_BROWSER_SCRIPT_PARTS) {\n  if (!scriptsDir) throw new Error('scriptsDir is required');\n  return parts.map((part, index) => ({\n    ...part,\n    index,\n    path: path.join(scriptsDir, part.file),\n  }));\n}\n\nexport function assertLiveBrowserScriptParts(parts, exists = fs.existsSync) {\n  for (const part of parts) {\n    if (!exists(part.path)) {\n      throw new Error(`Live browser script part missing: ${part.name} (${part.path})`);\n    }\n  }\n  return parts;\n}\n\nexport function readLiveBrowserScriptParts(parts, readFile = (filePath) => fs.readFileSync(filePath, 'utf-8')) {\n  return parts.map((part) => ({\n    ...part,\n    source: readFile(part.path),\n  }));\n}\n\nexport function assembleLiveBrowserScript({\n  token,\n  port,\n  vocabulary,\n  commandPrefix = '/',\n  appRoot = null,","sourceCodeStart":6,"sourceCodeEnd":42,"githubUrl":"https://github.com/pbakaus/impeccable/blob/d14711ae3d1a1dd62dee61a358d27f107c51ccd0/plugin/skills/impeccable/scripts/live/browser-script-parts.mjs#L6-L42","documentation":"Thrown by assertLiveBrowserScriptParts() when one of the three canonical browser script files (session-state, dom-helpers, browser-ui -> live-browser-session.js, live-browser-dom.js, live-browser.js) is missing from scriptsDir. resolveLiveBrowserScriptParts() joins scriptsDir with each part.file; assertLiveBrowserScriptParts() then checks fs.existsSync on each path. The assemble step cannot proceed without all three because the browser bundle is built by concatenating their sources.","triggerScenarios":"scriptsDir pointed at the wrong directory (e.g. plugin path vs source path mismatch); a script file was deleted/moved during a refactor; running against a partial install where the browser script set wasn't copied; tests passed a custom scriptsDir missing one file. The check is injected with an `exists` function for testability, but in production it's fs.existsSync.","commonSituations":"Skill installed via a path that doesn't include the browser scripts (partial npm/git checkout); build step that copies scripts but skipped *.js; version mismatch where LIVE_BROWSER_SCRIPT_PARTS added a new file not present in older installs; running from a source tree after `git clean` removed generated files.","solutions":["Ensure scriptsDir contains live-browser-session.js, live-browser-dom.js, and live-browser.js (the LIVE_BROWSER_SCRIPT_PARTS list).","Reinstall or re-clone the skill so the scripts directory is complete.","If running from source, run the build (`bun run build`) to regenerate any missing browser scripts.","Point the caller at the correct scripts directory — the assembled bundle uses `path.join(scriptsDir, part.file)`."],"exampleFix":"// before\nconst parts = resolveLiveBrowserScriptParts(wrongDir);\nassertLiveBrowserScriptParts(parts);\n\n// after\nconst scriptsDir = path.join(__dirname, 'scripts'); // the dir holding live-browser*.js\nconst parts = resolveLiveBrowserScriptParts(scriptsDir);\nassertLiveBrowserScriptParts(parts);","handlingStrategy":"validation","validationCode":"import { resolveLiveBrowserScriptParts, assertLiveBrowserScriptParts } from './live/browser-script-parts.mjs';\nimport fs from 'node:fs';\nconst parts = resolveLiveBrowserScriptParts(scriptsDir);\nconst missing = parts.filter((p) => !fs.existsSync(p.path));\nif (missing.length) {\n  throw new Error('Browser script dir incomplete; reinstall the skill. Missing: ' + missing.map((m) => m.file).join(', '));\n}\nassertLiveBrowserScriptParts(parts);","typeGuard":null,"tryCatchPattern":"try {\n  assertLiveBrowserScriptParts(parts);\n} catch (err) {\n  if (/Live browser script part missing/.test(err.message)) {\n    // reinstall the skill or rebuild browser scripts (bun run build:browser)\n    console.error(err.message, '— reinstall the impeccable skill.');\n    process.exit(1);\n  }\n  throw err;\n}","preventionTips":["Treat the scripts directory as atomic — all three live-browser*.js files must travel together.","After cloning or installing, run `bun run build:browser` (or the full build) to regenerate any missing browser scripts.","In tests, inject a stubbed `exists` fn into assertLiveBrowserScriptParts rather than deleting real files."],"tags":["live-browser","filesystem","install-integrity"],"backgroundTag":null,"analyzedSha":"d14711ae3d1a1dd62dee61a358d27f107c51ccd0","analyzedAt":"2026-08-13T00:52:25.771Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}