paperclipai/paperclip · error · Error

Invalid published report URL

Error message

Invalid published report URL

What it means

The safeUrl helper inside writeProtocolEvalPublicationLinks validates that report and history links are absolute https URLs without embedded credentials or control/HTML characters, then re-emits a normalized href. This error means one of the URLs to publish failed that check, so the script stops rather than emitting a potentially unsafe link into GitHub Actions outputs.

Source

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

    index,
    "no-cache",
  );
  return {
    campaignId: campaign.campaignId,
    bundleDigest: manifest.bundleDigest,
    historySize: history.campaigns.length,
    reportUrl: `${validatedDestination.publicBaseUrl}/${campaignPrefix}/index.html`,
    historyUrl: `${validatedDestination.publicBaseUrl}/${validatedDestination.prefix}/index.html`,
  };
}

export async function writeProtocolEvalPublicationLinks(result, environment = process.env) {
  const { campaignId, reportUrl, historyUrl } = result;
  if (!SAFE_CAMPAIGN.test(campaignId)) throw new Error("Invalid published campaign ID");
  const safeUrl = (value) => {
    const url = new URL(value);
    if (url.protocol !== "https:" || url.username || url.password || /[\r\n<>]/.test(value))
      throw new Error("Invalid published report URL");
    return url.href;
  };
  const report = safeUrl(reportUrl);
  const history = safeUrl(historyUrl);
  if (environment.GITHUB_OUTPUT)
    await appendFile(environment.GITHUB_OUTPUT, `report_url=${report}\nhistory_url=${history}\n`);
  if (environment.GITHUB_STEP_SUMMARY)
    await appendFile(environment.GITHUB_STEP_SUMMARY, `## Published Runner Evalbook\n\n[Open this run's Evalbook](<${report}>) · [All eval runs](<${history}>)\n\nCampaign: \`${campaignId}\`\n\nPublic replay uses the Runner Lab theme; full evidence is in the workflow artifact.\n`);
}

async function main() {
  const result = await publishProtocolEvalHistory({
    viewerRoot: process.env.PAPERCLIP_RUNNER_PROTOCOL_EVAL_VIEWER_DIR,
    reportRoot: resolve(
      process.env.PAPERCLIP_RUNNER_PROTOCOL_EVAL_PUBLIC_REPORT_DIR ??
        "runner-protocol-eval-public-report",
    ),
    destination: {

View on GitHub (pinned to 01ad858492)

Solutions

  1. Ensure the published site base URL uses https (fix publicBaseUrl/prefix configuration)
  2. Pass complete absolute URLs, not relative paths, for reportUrl/historyUrl
  3. Strip whitespace/control characters from the URL before calling
  4. Verify no credentials are embedded in the URL (use env-based auth instead)

Example fix

// before
const reportUrl = 'http://example.com/report.html';
// after
const reportUrl = 'https://example.com/report.html';
Defensive patterns

Strategy: validation

Validate before calling

const u = new URL(reportUrl); if (u.protocol !== 'https:' || u.username || u.password) throw new Error('reportUrl must be credentialess https');

Type guard

const isSafeHttpsUrl = (v) => { try { const u = new URL(v); return u.protocol === 'https:' && !u.username && !u.password && !/[\r\n<>]/.test(v); } catch { return false; } };

Try / catch

try { await writeProtocolEvalPublicationLinks(result); } catch (e) { if (e.message === 'Invalid published report URL') console.error('Check reportUrl/historyUrl:', result.reportUrl, result.historyUrl); throw e; }

Prevention

When it happens

Trigger: Passing reportUrl or historyUrl that is http: (not https), includes user:pass@ credentials, is not a parseable URL, or contains \r, \n, '<', or '>' characters.

Common situations: Local dev publishes an http://localhost link; a report path is passed instead of a full URL; a URL got built by string concatenation including newlines; a misconfigured base URL (publicBaseUrl) is http.

Understand the failure class

Background: "Invalid URL" errors: why new URL(), URI.parse, and reqwest::Url reject your string — missing scheme, whitespace, and bad path format — this error's family across 39 libraries.

Related errors


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