{"record":{"id":"6902ef1e441bb932","repo":"pbakaus/impeccable","slug":"preflight-returned-no-scaffold-metadata","errorCode":null,"errorMessage":"preflight returned no scaffold metadata","messagePattern":"preflight returned no scaffold metadata","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"skill/scripts/live/generation-preflight.mjs","lineNumber":92,"sourceCode":"  scriptsDir,\n  execFileImpl = execFileAsync,\n  timeoutMs = PREFLIGHT_TIMEOUT_MS,\n  cache = sourceResolutionCache,\n} = {}) {\n  const command = buildGenerationPreflight(event, scriptsDir, { cache });\n  if (!command) {\n    return { ok: false, skipped: true, reason: 'insufficient_locator' };\n  }\n\n  const startedAt = performance.now();\n  try {\n    const { stdout } = await execFileImpl(process.execPath, command.args, {\n      cwd,\n      encoding: 'utf-8',\n      timeout: timeoutMs,\n    });\n    const line = String(stdout).trim().split('\\n').filter(Boolean).pop();\n    if (!line) throw new Error('preflight returned no scaffold metadata');\n    const scaffold = JSON.parse(line);\n    // Cache the resolved SOURCE file (route source, not the svelte manifest) so\n    // the next generate on this target skips the tree search.\n    const resolvedSource = scaffold.sourceFile || scaffold.file;\n    if (cache && command.signature && typeof resolvedSource === 'string') {\n      cache.set(command.signature, resolvedSource);\n    }\n    return {\n      ok: true,\n      mode: command.mode,\n      durationMs: performance.now() - startedAt,\n      scaffold,\n    };\n  } catch (error) {\n    // Evict a stale/failed resolution so the next attempt does a full search\n    // (the element may have moved out of the previously cached file).\n    if (cache && command.signature) cache.delete(command.signature);\n    return {","sourceCodeStart":74,"sourceCodeEnd":110,"githubUrl":"https://github.com/pbakaus/impeccable/blob/f88b2837a7d7c3182e46307bbbb091a1ed547571/skill/scripts/live/generation-preflight.mjs#L74-L110","documentation":"runGenerationPreflight() (skill/scripts/live/generation-preflight.mjs) spawns `node live-insert.mjs|live-wrap.mjs --id ... --defer-source-write ...` with a 15s timeout to scaffold a generate event before the agent takes over. The helper's stdout is expected to end with a JSON metadata line, which is then JSON.parsed and its sourceFile/file cached by target signature. This error means the subprocess exited 0 but produced no non-empty stdout line at all — the metadata line is simply absent.","triggerScenarios":"An older live-insert.mjs/live-wrap.mjs in scriptsDir that doesn't implement the trailing metadata line (version mismatch with the server); a quiet not-found code path that exits successfully without printing; output swallowed by a wrapper; stdout redirected inside the helper.","commonSituations":"Partial skill updates leaving new live-server.mjs paired with stale helper scripts; custom installs where scriptsDir mixes versions; helper behavior changing across releases while the cached signature path expects the new format.","solutions":["Re-run the helper manually with the same arguments (visible in server logs) and inspect stdout — no trailing JSON line confirms the mismatch","Make scriptsDir contain the same skill version as the server: refresh/reinstall the skill or rebuild in the repo","If the helper prints a not-found/quiet result, fix the locator (element id/classes/tag) so the scaffold actually resolves","Keep server and helper scripts updated together — the preflight contract (exit 0 + last-line JSON) is version-coupled"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"import fs from 'node:fs';\nimport path from 'node:path';\n\n// Before relying on preflight, confirm the helper this server version expects\n// is the one actually present in scriptsDir.\nfor (const helper of ['live-insert.mjs', 'live-wrap.mjs']) {\n  const p = path.join(scriptsDir, helper);\n  if (!fs.existsSync(p)) throw new Error(`helper missing: ${p}`);\n}","typeGuard":null,"tryCatchPattern":"const result = await runGenerationPreflight(event, { cwd, scriptsDir });\nif (!result.ok && result.reason?.includes('preflight returned no scaffold metadata')) {\n  // Version/install mismatch: run the printed helper args manually,\n  // then refresh the skill so server and helpers share one version.\n  logRecoveryHint(result.reason);\n}","preventionTips":["Keep live-server.mjs and live-insert/live-wrap.mjs from the same skill version — the stdout metadata contract is version-coupled","After partial updates, smoke-test one generate event before a long session","When embedding, point scriptsDir at the complete scripts tree of one release"],"tags":["subprocess","scaffold","version-mismatch","live"],"backgroundTag":"empty-output-from-subprocess","analyzedSha":"f88b2837a7d7c3182e46307bbbb091a1ed547571","analyzedAt":"2026-08-18T04:58:36.608Z","contentChangedAt":"2026-08-18T04:58:36.608Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}