pbakaus/impeccable · warning · Error
preflight returned no scaffold metadata
Error message
preflight returned no scaffold metadata
What it means
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.
Source
Thrown at plugin/skills/impeccable/scripts/live/generation-preflight.mjs:92
scriptsDir,
execFileImpl = execFileAsync,
timeoutMs = PREFLIGHT_TIMEOUT_MS,
cache = sourceResolutionCache,
} = {}) {
const command = buildGenerationPreflight(event, scriptsDir, { cache });
if (!command) {
return { ok: false, skipped: true, reason: 'insufficient_locator' };
}
const startedAt = performance.now();
try {
const { stdout } = await execFileImpl(process.execPath, command.args, {
cwd,
encoding: 'utf-8',
timeout: timeoutMs,
});
const line = String(stdout).trim().split('\n').filter(Boolean).pop();
if (!line) throw new Error('preflight returned no scaffold metadata');
const scaffold = JSON.parse(line);
// Cache the resolved SOURCE file (route source, not the svelte manifest) so
// the next generate on this target skips the tree search.
const resolvedSource = scaffold.sourceFile || scaffold.file;
if (cache && command.signature && typeof resolvedSource === 'string') {
cache.set(command.signature, resolvedSource);
}
return {
ok: true,
mode: command.mode,
durationMs: performance.now() - startedAt,
scaffold,
};
} catch (error) {
// Evict a stale/failed resolution so the next attempt does a full search
// (the element may have moved out of the previously cached file).
if (cache && command.signature) cache.delete(command.signature);
return {View on GitHub (pinned to d14711ae3d)
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.
Example fix
// before: caller sees scaffoldError = 'preflight returned no scaffold metadata'
// after: run the helper manually to diagnose
// node ./scripts/live-wrap.mjs --id test --count 3 --defer-source-write --classes btn
// expected: a single JSON line on stdout like {"sourceFile":"src/App.jsx","line":12,...} Defensive patterns
Strategy: fallback
Try / catch
// runGenerationPreflight already converts this throw into { ok:false, error }.
// Callers should branch on result.ok rather than try/catching:
const result = await runGenerationPreflight(event, { cwd, scriptsDir });
if (!result.ok) {
// result.error holds 'preflight returned no scaffold metadata' (or a timeout)
// fall back to agent-driven generation without a scaffold hint
return { scaffold: null, scaffoldError: result.error, fallback: true };
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
AI-assisted analysis of pbakaus/impeccable@d14711ae3d (2026-08-13).
Data as JSON: /api/errors/cb54917db45d3221.
Report an issue: GitHub.