can1357/oh-my-pi · error
Finding ${finding.id} contains duplicate evidence ids
Error message
Finding ${finding.id} contains duplicate evidence ids What it means
parseSecurityScanBundle checks that every finding's evidence entries have unique ids by comparing Set size to array length. Duplicate evidence ids within one finding indicate malformed evidence collection — deduplication must happen at production time because consumers key on evidence.id.
Source
Thrown at packages/coding-agent/src/security/contracts/validation.ts:54
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) {
throw new Error(`Finding ${finding.id} contains duplicate occurrence ids`);
}
for (const occurrence of finding.occurrences) {
for (const evidenceId of occurrence.evidenceIds) {
if (!evidenceIds.has(evidenceId)) {
throw new Error(`Occurrence ${occurrence.id} references missing evidence: ${evidenceId}`);
}
}
}
}
return bundle;
}
View on GitHub (pinned to 9690622007)
Solutions
- Deduplicate the evidence array by id in the bundle JSON before loading.
- Fix the importer/generator so evidence ids are unique (e.g. derive from result index or a stable hash of the evidence content).
- Re-run the scan to regenerate a clean bundle if the source store is corrupted.
Example fix
// before finding.evidence = [...oldEvidence, ...newEvidence]; // overlapping entries // after const merged = new Map(finding.evidence.map(e => [e.id, e])); finding.evidence = [...merged.values()];
Defensive patterns
Strategy: validation
Validate before calling
for (const f of bundle.findings) {
const ids = f.evidence.map(e => e.id);
if (new Set(ids).size !== ids.length) throw new Error(`duplicate evidence ids in finding ${f.id}`);
} Type guard
function hasUniqueEvidenceIds(finding: SecurityFinding): boolean {
const ids = finding.evidence.map(e => e.id);
return new Set(ids).size === ids.length;
} Try / catch
try {
const bundle = readBundle(scanId);
} catch (err) {
if (err instanceof Error && err.message.includes("duplicate evidence ids")) {
// regenerate or deduplicate the bundle before retrying
} else throw err;
} Prevention
- Build evidence arrays through Map/id-keyed insertion so duplicates collapse automatically.
- Make evidence ids deterministic (hash of content or location) rather than sequence-based.
- Validate bundles after any import transform, before persisting.
When it happens
Trigger: Calling bundle()/readBundle()/importSarif()/importCodexSecurityBundle() on a bundle where a finding's evidence array contains two entries with the same id — typically from an importer appending the same evidence twice or a generator bug.
Common situations: SARIF imports where a result maps to the same code location multiple times and the import code assigns the same evidence id each time; retries during scan generation that re-append evidence without clearing the array.
Related errors
- Finding ${finding.id} contains duplicate occurrence ids
- lookbackDays must be a positive integer or 'all'
- Security scan contains duplicate finding ids
- Security scan manifest contains duplicate finding references
- Finding ${finding.id} belongs to ${finding.scanId}, expected
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/25c8b92663239943.
Report an issue: GitHub.