can1357/oh-my-pi · error

Security scan manifest contains duplicate finding references

Error message

Security scan manifest contains duplicate finding references

What it means

The bundle's scan manifest (scan.findingIds) must list each finding at most once. Duplicated manifest references indicate a corrupt or hand-edited manifest and would double-count findings in consumers, so parseSecurityScanBundle rejects the bundle.

Source

Thrown at packages/coding-agent/src/security/contracts/validation.ts:39

}

export function parseSecurityScanPlan(value: unknown): SecurityScanPlan {
	const { securityScanPlanSchema } = getSecurityContractSchemas();
	const result = securityScanPlanSchema(value);
	if (result instanceof type.errors) throw schemaError("Security scan plan", result);
	return result as SecurityScanPlan;
}

export function parseSecurityScanBundle(value: unknown): SecurityScanBundle {
	const { securityScanBundleSchema } = getSecurityContractSchemas();
	const result = securityScanBundleSchema(value);
	if (result instanceof type.errors) throw schemaError("Security scan bundle", result);
	const bundle = result as SecurityScanBundle;
	const findingIds = new Set(bundle.findings.map(finding => finding.id));
	if (findingIds.size !== bundle.findings.length) throw new Error("Security scan contains duplicate finding ids");
	const referencedFindingIds = new Set(bundle.scan.findingIds);
	if (referencedFindingIds.size !== bundle.scan.findingIds.length) {
		throw new Error("Security scan manifest contains duplicate finding references");
	}
	for (const findingId of referencedFindingIds) {
		if (!findingIds.has(findingId)) throw new Error(`Security scan references missing finding: ${findingId}`);
	}
	for (const findingId of findingIds) {
		if (!referencedFindingIds.has(findingId))
			throw new Error(`Security scan omits finding from manifest: ${findingId}`);
	}
	for (const finding of bundle.findings) {
		if (finding.scanId !== bundle.scan.id) {
			throw new Error(`Finding ${finding.id} belongs to ${finding.scanId}, expected ${bundle.scan.id}`);
		}
		const evidenceIds = new Set(finding.evidence.map(evidence => evidence.id));
		if (evidenceIds.size !== finding.evidence.length) {
			throw new Error(`Finding ${finding.id} contains duplicate evidence ids`);
		}
		const occurrenceIds = new Set(finding.occurrences.map(occurrence => occurrence.id));
		if (occurrenceIds.size !== finding.occurrences.length) {

View on GitHub (pinned to 9690622007)

Solutions

  1. Regenerate the bundle so scan.findingIds is derived as the unique set of finding ids
  2. Deduplicate the manifest before parse: findingIds: [...new Set(raw.scan.findingIds)]
  3. Validate pre-parse: compare new Set(manifest).size against manifest.length
  4. Fix the exporting tool to build the manifest from the findings array

Example fix

// before
parseSecurityScanBundle(raw); // raw.scan.findingIds has a duplicate
// after
raw.scan.findingIds = [...new Set(raw.scan.findingIds)];
parseSecurityScanBundle(raw);
Defensive patterns

Strategy: validation

Validate before calling

const m = raw.scan.findingIds;
if (new Set(m).size !== m.length) throw new Error("Manifest has duplicate finding references");

Try / catch

try {
	bundle = parseSecurityScanBundle(value);
} catch (err) {
	if (err instanceof Error && err.message === "Security scan manifest contains duplicate finding references") {
		raw.scan.findingIds = [...new Set(raw.scan.findingIds)];
		bundle = parseSecurityScanBundle(raw);
	} else throw err;
}

Prevention

When it happens

Trigger: Parsing a bundle JSON where bundle.scan.findingIds contains the same id twice (findings array itself may be fine).

Common situations: Scripted bundle generation appending to findingIds instead of replacing it; manual edits to exported JSON; a merge tool that deduplicated findings but not the manifest.

Related errors


AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31). Data as JSON: /api/errors/fa68ca785001fef9. Report an issue: GitHub.