{"record":{"id":"cb54917db45d3221","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":"Error","httpStatus":null,"severity":"warning","filePath":"plugin/skills/impeccable/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/d14711ae3d1a1dd62dee61a358d27f107c51ccd0/plugin/skills/impeccable/scripts/live/generation-preflight.mjs#L74-L110","documentation":"Thrown inside runGenerationPreflight() after the spawned live-wrap.mjs/live-insert.mjs (--defer-source-write) completed: its stdout had no non-empty line to parse as scaffold JSON. The helper is expected to print a single JSON object describing the scaffolded wrapper; an empty stdout means the helper ran but printed nothing usable. The error is caught by the surrounding try/catch and converted into { ok:false, error } rather than propagated — so callers see scaffoldError, not a throw.","triggerScenarios":"live-wrap.mjs exited 0 but printed only whitespace or nothing (a bug or an early exit); the helper wrote its output to stderr instead of stdout; a newer helper version changed the output contract; the element locator matched but the helper short-circuited before printing. The preflight runs with a 15s timeout (PREFLIGHT_TIMEOUT_MS) so a hang shows up as a timeout error, not this.","commonSituations":"Version skew: the server's runGenerationPreflight expects JSON-on-stdout but an older/newer live-wrap.mjs prints differently; helper swallowed an exception and exited cleanly; refactor of live-wrap.mjs removed the final console.log of the scaffold. In practice this surfaces as the generate event falling back to scaffold_fallback with this message in scaffoldError.","solutions":["Manually run the preflight command (from buildGenerationPreflight: `node live-wrap.mjs --id ... --defer-source-write ...`) and inspect its stdout — you should see one JSON line.","Align skill versions: runGenerationPreflight and live-wrap.mjs/live-insert.mjs must come from the same build.","If live-wrap.mjs is genuinely silent, debug why (check its argument parsing and early-return paths).","Increase logging in the helper to confirm it reaches the print step; the preflight only reads stdout, not stderr."],"exampleFix":"// before: caller sees scaffoldError = 'preflight returned no scaffold metadata'\n// after: run the helper manually to diagnose\n// node ./scripts/live-wrap.mjs --id test --count 3 --defer-source-write --classes btn\n// expected: a single JSON line on stdout like {\"sourceFile\":\"src/App.jsx\",\"line\":12,...}","handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":"// runGenerationPreflight already converts this throw into { ok:false, error }.\n// Callers should branch on result.ok rather than try/catching:\nconst result = await runGenerationPreflight(event, { cwd, scriptsDir });\nif (!result.ok) {\n  // result.error holds 'preflight returned no scaffold metadata' (or a timeout)\n  // fall back to agent-driven generation without a scaffold hint\n  return { scaffold: null, scaffoldError: result.error, fallback: true };\n}","preventionTips":["Keep live-wrap.mjs/live-insert.mjs and generation-preflight.mjs from the same build so the stdout JSON contract holds.","If you refactor live-wrap.mjs, preserve the single-line JSON scaffold print that preflight parses (String(stdout).trim().split('\\\\n').filter(Boolean).pop()).","Manually run the preflight command when debugging — its stdout must be one JSON object."],"tags":["live-generate","preflight","subprocess","scaffold"],"backgroundTag":null,"analyzedSha":"d14711ae3d1a1dd62dee61a358d27f107c51ccd0","analyzedAt":"2026-08-13T00:52:25.771Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}