can1357/oh-my-pi · error
Security scan omits finding from manifest: ${findingId}
Error message
Security scan omits finding from manifest: ${findingId} What it means
The inverse check: every finding in the findings array must be listed in scan.findingIds. A finding omitted from the manifest would be invisible to consumers that trust the manifest index, so parseSecurityScanBundle throws with the orphaned finding id.
Source
Thrown at packages/coding-agent/src/security/contracts/validation.ts:46
}
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) {
for (const evidenceId of occurrence.evidenceIds) {
if (!evidenceIds.has(evidenceId)) {
throw new Error(`Occurrence ${occurrence.id} references missing evidence: ${evidenceId}`);
}View on GitHub (pinned to 9690622007)
Solutions
- Rebuild the manifest to include every finding: scan.findingIds = [...new Set(findings.map(f => f.id))] Re-export the scan from the tool so manifest and findings are generated together If the extra finding is unintended, remove it from findings instead of adding it to the manifest
- Fix the exporting pipeline to append to the manifest when adding findings
Example fix
// before parseSecurityScanBundle(raw); // finding orphaned from manifest // after raw.scan.findingIds = [...new Set(raw.findings.map(f => f.id))]; parseSecurityScanBundle(raw);
Defensive patterns
Strategy: validation
Validate before calling
const manifest = new Set(raw.scan.findingIds);
const orphaned = raw.findings.filter((f: { id: string }) => !manifest.has(f.id));
if (orphaned.length) throw new Error(`Findings missing from manifest: ${orphaned.map(f => f.id).join(", ")}`); Try / catch
try {
bundle = parseSecurityScanBundle(value);
} catch (err) {
if (err instanceof Error && err.message.startsWith("Security scan omits finding from manifest:")) {
raw.scan.findingIds = [...new Set(raw.findings.map(f => f.id))];
bundle = parseSecurityScanBundle(raw);
} else throw err;
} Prevention
- Derive the manifest from the findings array, never maintain it by hand
- Regenerate exports after adding findings rather than patching JSON
- Round-trip generated bundles through parseSecurityScanBundle as a build check
When it happens
Trigger: Parsing a bundle where a finding exists in bundle.findings but its id is missing from bundle.scan.findingIds.
Common situations: Appending new findings to an export without updating the manifest; a generator bug that snapshots the manifest before all findings are collected; hand-merging findings from another scan into the array.
Related errors
- Security scan references missing finding: ${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/a0bbfc872ecb6693.
Report an issue: GitHub.