can1357/oh-my-pi · error

Security scan references missing finding: ${findingId}

Error message

Security scan references missing finding: ${findingId}

What it means

Every id listed in scan.findingIds must correspond to an actual finding in the findings array. If the manifest references a finding that does not exist, the bundle is internally inconsistent and parseSecurityScanBundle throws with the missing id.

Source

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

	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) {
			throw new Error(`Finding ${finding.id} contains duplicate occurrence ids`);
		}
		for (const occurrence of finding.occurrences) {

View on GitHub (pinned to 9690622007)

Solutions

  1. Rebuild the manifest from the findings array: scan.findingIds = findings.map(f => f.id)
  2. Re-export the full scan without filtering the findings array
  3. Validate pre-parse and strip unreferenced manifest entries
  4. Regenerate the bundle from the scanner if the file was truncated

Example fix

// before
parseSecurityScanBundle(raw); // manifest references id not in findings
// after
const ids = new Set(raw.findings.map(f => f.id));
raw.scan.findingIds = raw.scan.findingIds.filter(id => ids.has(id));
parseSecurityScanBundle(raw);
Defensive patterns

Strategy: validation

Validate before calling

const ids = new Set(raw.findings.map((f: { id: string }) => f.id));
const missing = raw.scan.findingIds.filter((id: string) => !ids.has(id));
if (missing.length) throw new Error(`Manifest references missing findings: ${missing.join(", ")}`);

Try / catch

try {
	bundle = parseSecurityScanBundle(value);
} catch (err) {
	if (err instanceof Error && err.message.startsWith("Security scan references missing finding:")) {
		raw.scan.findingIds = raw.scan.findingIds.filter(id => ids.has(id));
		bundle = parseSecurityScanBundle(raw);
	} else throw err;
}

Prevention

When it happens

Trigger: Parsing a bundle where scan.findingIds contains an id absent from bundle.findings — e.g. findings were filtered out but the manifest was left intact.

Common situations: Hand-editing an export to drop findings without updating the manifest; a partial/truncated export (findings array cut short); merging bundles and dropping findings while keeping one combined manifest.

Related errors


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