paperclipai/paperclip · error · Error

Evalbook requires the chat viewer. Run pnpm --filter @paperc

Error message

Evalbook requires the chat viewer. Run pnpm --filter @paperclipai/paperclip-runner build:issue-thread first.

What it means

renderRunnerWorkflowWithCanonicalEvalbook requires the built chat viewer (dist-issue-thread/index.html) to bundle into the Evalbook, and throws this error when the viewer build output is absent. The script tells you the exact pnpm build command to produce it.

Source

Thrown at packages/paperclip-runner/scripts/render-runner-workflow-evalbook.mjs:317

        );
    });
  });
}

export async function renderRunnerWorkflowWithCanonicalEvalbook({
  packageRoot,
  outputDirectory,
  report,
  caseForId,
  environment = process.env,
}) {
  const program = await resolveCanonicalEvalProgram(packageRoot, environment);
  const viewerRoot = resolve(
    environment.PAPERCLIP_EVAL_VIEWER_ROOT ??
      resolve(packageRoot, "dist-issue-thread"),
  );
  await access(resolve(viewerRoot, "index.html")).catch(() => {
    throw new Error(
      "Evalbook requires the chat viewer. Run pnpm --filter @paperclipai/paperclip-runner build:issue-thread first.",
    );
  });
  const runsRoot = resolve(outputDirectory, "evalbook-runs");
  await rm(runsRoot, { recursive: true, force: true });
  const attempts = await writeRunnerWorkflowEvalbookAttempts({
    report,
    runsRoot,
    caseForId,
  });
  await Promise.all([
    rm(resolve(outputDirectory, "attempts"), { recursive: true, force: true }),
    rm(resolve(outputDirectory, "tests"), { recursive: true, force: true }),
    rm(resolve(outputDirectory, "index.html"), { force: true }),
    rm(resolve(outputDirectory, "latest.html"), { force: true }),
    rm(resolve(outputDirectory, "live-report.html"), { force: true }),
    rm(resolve(outputDirectory, "deterministic-report.html"), { force: true }),
  ]);

View on GitHub (pinned to 01ad858492)

Solutions

  1. Run `pnpm --filter @paperclipai/paperclip-runner build:issue-thread` and retry
  2. If using a custom viewer location, ensure PAPERCLIP_EVAL_VIEWER_ROOT points at a build output containing index.html
  3. Verify dist-issue-thread/index.html exists after the build (ls dist-issue-thread)
  4. In CI, add the viewer build step before the evalbook render step

Example fix

// before
node scripts/render-runner-workflow-evalbook.mjs ...
// after
pnpm --filter @paperclipai/paperclip-runner build:issue-thread && \
  node scripts/render-runner-workflow-evalbook.mjs ...
Defensive patterns

Strategy: fallback

Validate before calling

await access(join(viewerRoot,'index.html')).catch(() => { throw new Error('Viewer missing; run pnpm --filter @paperclipai/paperclip-runner build:issue-thread'); });

Type guard

null

Try / catch

try { await renderRunnerWorkflowEvalbook(...); } catch (e) { if (e.message.includes('chat viewer')) { execSync('pnpm --filter @paperclipai/paperclip-runner build:issue-thread', { stdio: 'inherit' }); return renderRunnerWorkflowEvalbook(...); } throw e; }

Prevention

When it happens

Trigger: Running the renderer before building @paperclipai/paperclip-runner's issue-thread viewer; a clean CI workspace where only `pnpm install` ran; PAPERCLIP_EVAL_VIEWER_ROOT pointing at a directory without index.html.

Common situations: Fresh clone followed directly by the evalbook script; switching branches where dist-issue-thread was gitignored and never rebuilt; a typo'd PAPERCLIP_EVAL_VIEWER_ROOT.

Understand the failure class

Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.

Related errors


AI-assisted analysis of paperclipai/paperclip@01ad858492 (2026-09-10). Data as JSON: /api/errors/7fb94d75c660b10e. Report an issue: GitHub.