{"record":{"id":"42da1e73cb0109e6","repo":"can1357/oh-my-pi","slug":"unknown-security-operation-operationid","errorCode":null,"errorMessage":"Unknown security operation: ${operationId}","messagePattern":"Unknown security operation: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/security/coordinator.ts","lineNumber":549,"sourceCode":"\t\t\t.sort((left, right) => right.createdAt.localeCompare(left.createdAt));\n\t}\n\n\tasync cancel(operationId: string): Promise<boolean> {\n\t\tawait this.#ensureRecovered();\n\t\tconst record = this.#operations.get(operationId);\n\t\tif (!record) return false;\n\t\tif ([\"completed\", \"partial\", \"cancelled\", \"failed\"].includes(record.snapshot.phase)) return false;\n\t\tif (record.snapshot.jobId && this.#host.asyncJobManager) {\n\t\t\treturn this.#host.asyncJobManager.cancel(record.snapshot.jobId, { ownerId: this.#host.agentId });\n\t\t}\n\t\trecord.abortController?.abort(new Error(\"Security scan cancelled\"));\n\t\treturn true;\n\t}\n\n\tasync wait(operationId: string): Promise<SecurityOperationSnapshot> {\n\t\tawait this.#ensureRecovered();\n\t\tconst record = this.#operations.get(operationId);\n\t\tif (!record) throw new Error(`Unknown security operation: ${operationId}`);\n\t\tawait record.promise;\n\t\treturn { ...record.snapshot };\n\t}\n\n\t#update(record: SecurityOperationRecord, phase: SecurityOperationPhase, error?: string): void {\n\t\trecord.snapshot.phase = phase;\n\t\trecord.snapshot.updatedAt = toIsoTimestamp(this.#now);\n\t\trecord.snapshot.error = error;\n\t}\n\n\tasync #run(\n\t\trecord: SecurityOperationRecord,\n\t\tplan: SecurityScanPlan,\n\t\tstore: SecurityStore,\n\t\tsignal: AbortSignal,\n\t\treportProgress?: (text: string) => Promise<void>,\n\t): Promise<void> {\n\t\tconst startedAt = toIsoTimestamp(this.#now);","sourceCodeStart":531,"sourceCodeEnd":567,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/security/coordinator.ts#L531-L567","documentation":"wait() blocks until the operation with the given id finishes, but only ids registered in this coordinator's in-memory #operations map (including those recovered from interrupted scans) are waitable. An unknown id means no such operation exists in this process, and unlike status(), wait() does not rescan the disk for terminal bundles before giving up.","triggerScenarios":"Calling wait(operationId) with an id that was never returned by start(), an id from a previous process that recovery didn't register, a typo'd/copied id, or waiting on an operation started in a different session's coordinator.","commonSituations":"Restarting the process and waiting on a pre-restart operationId whose scan was already terminal (recovery skips completed scans); automation holding stale ids; polling wait() before start() returned the snapshot.","solutions":["Use the operationId exactly as returned by the start() snapshot — capture it at start time rather than reconstructing it.","Check existence first with status(operationId), which also rescans interrupted/terminal operations on disk and returns null instead of throwing.","If the id came from a prior process, use status() or listOperations() to find the recovered snapshot instead of wait().","Fix id storage/passing in your automation (persist the id from start() and pass it through)."],"exampleFix":"// before\nconst snap = await coordinator.wait(opId); // throws if unknown\n// after\nconst existing = await coordinator.status(opId);\nconst snap = existing ?? await coordinator.wait(opIdFromStart);","handlingStrategy":"try-catch","validationCode":"const known = await coordinator.status(operationId);\nif (!known) throw new Error(`operation ${operationId} unknown in this coordinator`);","typeGuard":null,"tryCatchPattern":"try {\n  const snap = await coordinator.wait(operationId);\n} catch (err) {\n  if (err instanceof Error && err.message.startsWith(\"Unknown security operation\")) {\n    const recovered = await coordinator.status(operationId); // rescans disk for terminal ops\n    if (!recovered) throw err;\n    return recovered;\n  } else throw err;\n}","preventionTips":["Persist the operationId returned by start() and reuse it verbatim for wait()/cancel().","After a process restart, use status() or listOperations() first — recovery may not register already-terminal operations.","Never wait on an id obtained from another coordinator instance or session."],"tags":["state","async","unknown-identifier"],"backgroundTag":"unknown-operation-id","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}