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

  1. Deduplicate occurrences by id in the offending finding before loading.
  2. Fix the producing code so occurrence ids are unique per finding (include location/result index in the id).
  3. 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

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


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