can1357/oh-my-pi · error · Error
Unknown security finding: ${findingId}
Error message
Unknown security finding: ${findingId} What it means
updateDisposition() locates the finding by id inside the loaded bundle's findings array. If no finding matches findingId it throws this error. The scan exists (otherwise error 2014 fires first); only the finding id is wrong.
Source
Thrown at packages/coding-agent/src/security/store.ts:370
}
return summaries;
}
async getFinding(scanId: string, findingId: string): Promise<SecurityFinding | null> {
const bundle = await this.getBundle(scanId);
return bundle?.findings.find(finding => finding.id === findingId) ?? null;
}
async updateDisposition(
scanId: string,
findingId: string,
disposition: SecurityDisposition,
): Promise<SecurityFinding> {
return withSecurityStoreWrite(this.#projectDirectory, async () => {
const bundle = await this.#getBundleUnlocked(scanId);
if (!bundle) throw new Error(`Unknown security scan: ${scanId}`);
const index = bundle.findings.findIndex(finding => finding.id === findingId);
if (index < 0) throw new Error(`Unknown security finding: ${findingId}`);
const canonicalDisposition: SecurityDisposition = { status: disposition.status };
if (disposition.rationale !== undefined) canonicalDisposition.rationale = disposition.rationale;
if (disposition.updatedAt !== undefined) canonicalDisposition.updatedAt = disposition.updatedAt;
if (disposition.actor !== undefined) canonicalDisposition.actor = disposition.actor;
const updated = { ...bundle.findings[index], disposition: canonicalDisposition };
bundle.findings[index] = parseSecurityFinding(updated);
if (bundle.sarif !== undefined) bundle.sarif = exportSecurityBundleToSarif(bundle);
await this.#putBundleUnlocked(bundle);
return bundle.findings[index];
});
}
async updateValidation(
scanId: string,
findingId: string,
validation: SecurityValidation,
evidence: readonly SecurityEvidence[] = [],
): Promise<SecurityFinding> {View on GitHub (pinned to 9690622007)
Solutions
- Look up valid ids first: (await store.getBundle(scanId))?.findings.map(f => f.id) and use an exact match.
- Use store.getFinding(scanId, findingId) to test existence before calling updateDisposition.
- Confirm the finding belongs to this scanId, not a sibling scan in the same store.
- If the finding was legitimately removed, decide whether the disposition is still meaningful — otherwise skip or re-run the scan.
Example fix
// before
await store.updateDisposition(scanId, 'finding-1', disposition); // wrong id scheme
// after
const finding = await store.getFinding(scanId, 'finding-1');
if (!finding) throw new Error('finding not in this scan');
await store.updateDisposition(scanId, finding.id, disposition); Defensive patterns
Strategy: type-guard
Validate before calling
const finding = await store.getFinding(scanId, findingId);
if (!finding) throw new Error(`finding ${findingId} not in scan ${scanId}`); Type guard
function isKnownFinding(f: SecurityFinding | null): f is SecurityFinding {
return f !== null;
} Try / catch
try {
await store.updateDisposition(scanId, findingId, disposition);
} catch (err) {
if (err instanceof Error && err.message.startsWith('Unknown security finding')) {
const bundle = await store.getBundle(scanId);
console.error(`valid ids: ${bundle?.findings.map(f => f.id).join(', ')}`);
} else throw err;
} Prevention
- Always source finding ids from the same bundle/scan you pass as scanId.
- Call getFinding() to verify existence before mutation.
- Refresh ids after re-scans; old generation ids may disappear.
- Watch for id truncation when copying from terminal output or logs.
When it happens
Trigger: Calling updateDisposition(scanId, findingId, disposition) where findingId is not present in that scan's findings — typo'd/copied-wrong id, the finding belongs to a different scan, or the finding was removed when the bundle was rewritten.
Common situations: Using a finding id from an older scan generation in a re-scanned bundle; id copied from a SARIF export with a different id scheme; truncation when copying ids; referencing a finding from the 'after' scan in compare() workflows.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- Unknown security scan: ${scanId}
- Unknown security validation evidence: ${evidenceId}
- Unknown security scan: ${beforeScanId}
- Plugin ${name} not found in runtime config
- Marketplace "${name}" not found
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/dea4fcb1662d9a40.
Report an issue: GitHub.