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
- Rebuild the manifest from the findings array: scan.findingIds = findings.map(f => f.id)
- Re-export the full scan without filtering the findings array
- Validate pre-parse and strip unreferenced manifest entries
- 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
- Always regenerate the manifest whenever findings are filtered or removed
- Check exports for truncation before parsing (file size, entry counts)
- Treat hand-edited bundle JSON as suspect; re-export instead
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
- Security scan omits finding from manifest: ${findingId}
- Security scan manifest contains duplicate finding references
- Runtime install at ${runtimeDir} declares no dependencies
- Unsupported language '{value}'. Supported: {}
- Unable to infer language from file extension: {}. Specify `l
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/c1b37c7442b10ee0.
Report an issue: GitHub.