{"record":{"id":"1ee8d88795156ac0","repo":"paperclipai/paperclip","slug":"runner-protocol-eval-history-public-base-url-must","errorCode":null,"errorMessage":"RUNNER_PROTOCOL_EVAL_HISTORY_PUBLIC_BASE_URL must be a credential-free HTTPS URL","messagePattern":"RUNNER_PROTOCOL_EVAL_HISTORY_PUBLIC_BASE_URL must be a credential-free HTTPS URL","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/paperclip-runner/scripts/publish-runner-protocol-eval-history.mjs","lineNumber":94,"sourceCode":"  if (\n    !normalizedPrefix ||\n    normalizedPrefix\n      .split(\"/\")\n      .some((segment) => !segment || segment === \".\" || segment === \"..\")\n  ) {\n    throw new Error(\n      \"RUNNER_PROTOCOL_EVAL_HISTORY_PREFIX must be a safe non-empty key prefix\",\n    );\n  }\n  const url = new URL(publicBaseUrl);\n  if (\n    url.protocol !== \"https:\" ||\n    url.username ||\n    url.password ||\n    url.search ||\n    url.hash\n  ) {\n    throw new Error(\n      \"RUNNER_PROTOCOL_EVAL_HISTORY_PUBLIC_BASE_URL must be a credential-free HTTPS URL\",\n    );\n  }\n  return {\n    bucket,\n    prefix: normalizedPrefix,\n    publicBaseUrl: url.href.replace(/\\/$/, \"\"),\n  };\n}\n\nexport function isPublicProtocolEvalPath(relativePath) {\n  if (\n    relativePath.includes(\"\\\\\") ||\n    relativePath.startsWith(\"/\") ||\n    relativePath\n      .split(\"/\")\n      .some((segment) => !segment || segment === \".\" || segment === \"..\")\n  ) {","sourceCodeStart":76,"sourceCodeEnd":112,"githubUrl":"https://github.com/paperclipai/paperclip/blob/01ad8584922b5d85292b1723cae71fa0d9b07a19/packages/paperclip-runner/scripts/publish-runner-protocol-eval-history.mjs#L76-L112","documentation":"Thrown by validateProtocolEvalHistoryDestination when the public base URL is not an HTTPS URL without credentials, query string, or hash. RUNNER_PROTOCOL_EVAL_HISTORY_PUBLIC_BASE_URL must be a clean https:// origin-style URL used to build public links to the published report.","triggerScenarios":"Setting RUNNER_PROTOCOL_EVAL_HISTORY_PUBLIC_BASE_URL to an http:// URL, embedding user:pass@ credentials, or including ?query or #fragment components.","commonSituations":"Using a local http:// mirror for testing; pasting a signed or credentialed URL from a cloud console; appending a cache-busting query parameter.","solutions":["Change the scheme to https:// (e.g. https://evals.example.com).","Remove any username/password, query string, and fragment from the URL.","Point the variable at the bare public CDN/site base URL only."],"exampleFix":"// before\nRUNNER_PROTOCOL_EVAL_HISTORY_PUBLIC_BASE_URL=http://admin:secret@evals.example.com?v=2\n// after\nRUNNER_PROTOCOL_EVAL_HISTORY_PUBLIC_BASE_URL=https://evals.example.com","handlingStrategy":"validation","validationCode":"const u = new URL(process.env.RUNNER_PROTOCOL_EVAL_HISTORY_PUBLIC_BASE_URL ?? '');\nif (u.protocol !== 'https:' || u.username || u.password || u.search || u.hash) throw new Error('base URL must be credential-free https');","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Configure only bare https:// origin URLs for public base URLs.","Never paste signed or credentialed console URLs into env config.","Add a CI preflight that parses and checks the URL components."],"tags":["config","env-var","url"],"backgroundTag":"invalid-url","analyzedSha":"01ad8584922b5d85292b1723cae71fa0d9b07a19","analyzedAt":"2026-09-10T03:14:50.855Z","contentChangedAt":"2026-09-10T03:14:50.855Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}