paperclipai/paperclip · error · Error

Refusing non-allowlisted public protocol eval path ${file}

Error message

Refusing non-allowlisted public protocol eval path ${file}

What it means

Every collected file path must match the allowlist defined by isPublicProtocolEvalPath (e.g. index.html, campaign.json, attempts/*/index.html, viewer/ assets). Any file outside that allowlist aborts publication naming the offending relative path, preventing unintended files from being exposed publicly.

Source

Thrown at packages/paperclip-runner/scripts/publish-runner-protocol-eval-history.mjs:157

export async function validatePublicProtocolEvalReport(
  reportRoot,
  { viewerRoot } = {},
) {
  const root = resolve(reportRoot);
  const files = await relativeFiles(root);
  const hasChat = files.some((file) =>
    /^attempts\/[^/]+\/index\.html$/.test(file),
  );
  const viewer = hasChat ? await trustedViewerFiles(viewerRoot) : null;
  if (!files.includes("index.html") || !files.includes("campaign.json")) {
    throw new Error(
      "Public protocol eval report requires index.html and campaign.json",
    );
  }
  for (const file of files) {
    if (!isPublicProtocolEvalPath(file)) {
      throw new Error(
        `Refusing non-allowlisted public protocol eval path ${file}`,
      );
    }
    const absolute = resolve(root, ...file.split("/"));
    const metadata = await stat(absolute);
    if (metadata.size === 0 || metadata.size > 12 * 1024 * 1024) {
      throw new Error(
        `Public protocol eval file exceeds its size boundary: ${file}`,
      );
    }
    if (file.startsWith("viewer/")) {
      const expected = viewer?.files.get(file);
      if (!expected || !expected.equals(await readFile(absolute)))
        throw new Error(
          `Public viewer asset differs from trusted build: ${file}`,
        );
      continue;
    }

View on GitHub (pinned to 01ad858492)

Solutions

  1. Inspect the named file; if it is not meant to be public, delete it from the report directory and re-run.
  2. If the file is legitimately part of the report, update isPublicProtocolEvalPath in the script to allowlist its pattern, then re-run.
  3. Regenerate the report into a clean directory so only generator output (no OS/editor droppings) is present.

Example fix

# before
public-report/.DS_Store   -> Refusing non-allowlisted path
# after
$ find public-report -name .DS_Store -delete
$ node scripts/publish-runner-protocol-eval-history.mjs ...
Defensive patterns

Strategy: validation

Validate before calling

import { readdirSync } from 'node:fs';
const allowed = /^(index\.html|campaign\.json|attempts\/[^/]+\/index\.html|viewer\/[^/]+)$/;
const offenders = [];
(function walk(dir, rel = '') {
  for (const e of readdirSync(dir, { withFileTypes: true })) {
    const p = rel ? `${rel}/${e.name}` : e.name;
    if (e.isDirectory()) walk(`${dir}/${e.name}`, p);
    else if (!allowed.test(p)) offenders.push(p);
  }
})(reportRoot);
if (offenders.length) throw new Error(`non-allowlisted: ${offenders.join(', ')}`);

Try / catch

try {
  await publishReport(root);
} catch (err) {
  if (String(err.message).startsWith('Refusing non-allowlisted public protocol eval path')) {
    console.error('Delete the stray file or extend the allowlist:', err.message);
  } else throw err;
}

Prevention

When it happens

Trigger: Publishing a report root containing extra files such as .DS_Store, editor backups (file~), raw JSON dumps, logs, or nested files not covered by the allowlist pattern.

Common situations: macOS .DS_Store or Thumbs.db inside the report dir; copying extra assets into the report folder; a newer generator emitting files the publisher doesn't allowlist; temp files left by a failed build.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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