can1357/oh-my-pi · error · Error
Unknown security scan: ${scanId}
Error message
Unknown security scan: ${scanId} What it means
updateDisposition() loads the full scan bundle; #getBundleUnlocked returns null when scans/<scanId>/scan.json does not exist (or the scan id fails the secscan_ format check). The method then throws this error because a disposition can only be recorded on an existing scan.
Source
Thrown at packages/coding-agent/src/security/store.ts:368
target: bundle.scan.target,
});
}
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,View on GitHub (pinned to 9690622007)
Solutions
- Verify the scan exists with await store.getScan(scanId) or store.listScans() and use a valid id before updating.
- Confirm you opened the same store (same repositoryRoot/stateRoot) that wrote the scan — project directories are keyed per repo.
- Check index.json scanIds to see whether the id was ever registered in this store.
- If the scan directory was deleted, re-run the scan and putBundle() before attempting updates.
Example fix
// before
await store.updateDisposition('secscan_9x', findingId, disposition); // typo'd id
// after
const scan = await store.getScan('secscan_9x');
if (scan) await store.updateDisposition(scan.id, findingId, disposition); Defensive patterns
Strategy: type-guard
Validate before calling
const scan = await store.getScan(scanId);
if (!scan) throw new Error(`scan ${scanId} not found in ${store.projectDirectory}`); Type guard
function isKnownScan(s: SecurityScan | null): s is SecurityScan {
return s !== null;
} Try / catch
try {
await store.updateDisposition(scanId, findingId, disposition);
} catch (err) {
if (err instanceof Error && err.message.startsWith('Unknown security scan')) {
const scans = await store.listScans();
console.error(`scan ${scanId} not found; known: ${scans.map(s => s.id).join(', ')}`);
} else throw err;
} Prevention
- Resolve scan ids from store.listScans() instead of copying them by hand.
- Keep one SecurityStore per repository; don't mix ids across stores.
- Trim/normalize ids coming from CLI args or config.
- Check that cleanup jobs don't delete scans whose ids are still referenced.
When it happens
Trigger: Calling updateDisposition(scanId, findingId, disposition) with a scanId that has no stored scan.json — typo'd id, scan deleted from disk, wrong store (different repositoryRoot/stateRoot so a different project directory), or a malformed id not matching /^secscan_[a-zA-Z0-9]+$/.
Common situations: Storing scan ids from logs with surrounding whitespace/quotes; referencing a scan from a different repo's store after a checkout switch; the scans/<id>/ directory partially removed while index.json still lists it; case/character mistakes when copying ids.
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: ${beforeScanId}
- Unknown security finding: ${findingId}
- Unknown security validation evidence: ${evidenceId}
- 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/ee0038e62ab8d88d.
Report an issue: GitHub.