can1357/oh-my-pi · error
Finding ${finding.id} contains duplicate occurrence ids
Error message
Finding ${finding.id} contains duplicate occurrence ids What it means
parseSecurityScanBundle enforces unique occurrence ids within each finding (Set size vs array length). Occurrences represent concrete code locations; duplicated ids break downstream lookup and deduplication, so the library rejects the bundle at parse time.
Source
Thrown at packages/coding-agent/src/security/contracts/validation.ts:58
}
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 occurrences by id in the offending finding before loading.
- Fix the producing code so occurrence ids are unique per finding (include location/result index in the id).
- Regenerate the bundle by re-running the security scan.
Example fix
// before finding.occurrences.push(occurrenceFrom(result)); // same id as an existing occurrence // after if (!finding.occurrences.some(o => o.id === occ.id)) finding.occurrences.push(occ);
Defensive patterns
Strategy: validation
Validate before calling
for (const f of bundle.findings) {
const ids = f.occurrences.map(o => o.id);
if (new Set(ids).size !== ids.length) throw new Error(`duplicate occurrence ids in finding ${f.id}`);
} Type guard
function hasUniqueOccurrenceIds(finding: SecurityFinding): boolean {
const ids = finding.occurrences.map(o => o.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 occurrence ids")) {
// deduplicate or regenerate the bundle
} else throw err;
} Prevention
- Include a per-finding sequence number or location hash in occurrence ids to guarantee uniqueness.
- Guard occurrence emission with an id-set check before push.
- On resumable scan runs, clear or merge prior occurrence state instead of appending.
When it happens
Trigger: Loading or importing a bundle where finding.occurrences has two entries sharing an id — usually caused by the scan session emitting the same occurrence twice or an importer mapping multiple SARIF results to one occurrence id.
Common situations: SARIF conversions where several results collapse onto the same location id; resumable scan runs that re-emit occurrences after a retry without clearing prior state.
Related errors
- Finding ${finding.id} contains duplicate evidence 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/db0ea9a59b1c459e.
Report an issue: GitHub.