paperclipai/paperclip · error · Error
Report campaign ID does not match publication target
Error message
Report campaign ID does not match publication target
What it means
After validating the report, createProtocolEvalBundleManifest cross-checks that the campaignId embedded in the report's campaign.json equals the campaignId argument the caller asked to publish for. A mismatch means the manifest would be filed under a different campaign than the report declares, breaking the immutable bundle addressing, so it throws.
Source
Thrown at packages/paperclip-runner/scripts/publish-runner-protocol-eval-history.mjs:254
) {
throw new Error("Public report campaign metadata is invalid");
}
return { files, campaign };
}
export async function createProtocolEvalBundleManifest(
reportRoot,
campaignId,
{ viewerRoot } = {},
) {
if (!SAFE_CAMPAIGN.test(campaignId))
throw new Error("Unsafe protocol eval campaign ID");
const { files, campaign } = await validatePublicProtocolEvalReport(
reportRoot,
{ viewerRoot },
);
if (campaign.campaignId !== campaignId)
throw new Error("Report campaign ID does not match publication target");
const entries = await Promise.all(
files.map(async (file) => {
const absolute = resolve(reportRoot, ...file.split("/"));
const [content, metadata] = await Promise.all([
readFile(absolute),
stat(absolute),
]);
return {
path: file,
sha256: createHash("sha256").update(content).digest("hex"),
bytes: metadata.size,
};
}),
);
return {
schema: "paperclip.runner-protocol-eval.bundle/v1",
campaignId,
bundleDigest: createHash("sha256")View on GitHub (pinned to 01ad858492)
Solutions
- Pass the campaign ID exactly as written in <reportRoot>/campaign.json
- Regenerate the report for the current run so its campaign.json matches the publication target
- Point reportRoot at the correct report directory for the given campaignId
- Read the report's campaign.json first and use its campaignId as the manifest argument
Example fix
// before
await createProtocolEvalBundleManifest("reports/old-run", "gha-99-1");
// after
const campaign = JSON.parse(await readFile("reports/old-run/campaign.json", "utf8"));
await createProtocolEvalBundleManifest("reports/old-run", campaign.campaignId); Defensive patterns
Strategy: validation
Validate before calling
const campaign = JSON.parse(fs.readFileSync(path.join(reportRoot, "campaign.json"), "utf8"));
if (campaign.campaignId !== targetCampaignId) throw new Error(`report is for ${campaign.campaignId}, not ${targetCampaignId}`); Try / catch
try {
await createProtocolEvalBundleManifest(reportRoot, campaignId);
} catch (e) {
if (String(e.message).includes("does not match publication target")) {
const declared = JSON.parse(fs.readFileSync(path.join(reportRoot, "campaign.json"), "utf8")).campaignId;
console.error(`report declares ${declared}; pass that id or regenerate the report`);
}
throw e;
} Prevention
- Always read campaign.json and use its campaignId as the publication target
- Do not reuse cached report directories across CI attempts
- Regenerate the report whenever the intended campaign ID changes
When it happens
Trigger: Calling createProtocolEvalBundleManifest(reportRoot, 'gha-9-1') against a reportRoot whose campaign.json says campaignId 'gha-8-2'; reusing a stale report directory while passing the current run's ID; publishing two different generated reports with a hard-coded campaign ID.
Common situations: CI retries that reuse a cached report from another attempt; locally testing the publish script with the wrong report directory; a copied/moved report directory containing another run's metadata.
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
- request.session.provider must match request.provider
- request.session.requestedModel must match request.model
- Chat Evalbook must not mix in legacy plain attempt pages
- Immutable campaign history changed for ${record.campaignId}
- Invalid status '${String(rawStatus)}'. Must be one of: ${PLU
AI-assisted analysis of paperclipai/paperclip@01ad858492 (2026-09-10).
Data as JSON: /api/errors/63748cc190206ef9.
Report an issue: GitHub.