paperclipai/paperclip · error · Error

Evalbook requires the chat viewer. Run pnpm --filter…

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.

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.

Appendix: 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)