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

  1. 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.
  2. Align skill versions: runGenerationPreflight and live-wrap.mjs/live-insert.mjs must come from the same build.
  3. If live-wrap.mjs is genuinely silent, debug why (check its argument parsing and early-return paths).
  4. 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

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.