can1357/oh-my-pi · error · ToolError

Unknown security operation: ${operationId}

Error message

Unknown security operation: ${operationId}

What it means

When action=status, the tool requires operation_id, looks it up via the security coordinator, and throws this ToolError if the coordinator returns no snapshot — i.e. no operation exists with that id (or it is no longer tracked).

Source

Thrown at packages/coding-agent/src/tools/security-scan.ts:173

						`Fingerprint: ${plan.fingerprint}.`,
						`Start it with action=start and plan_id=${plan.id}.`,
					].join(" "),
					{ action: params.action, plan: { id: plan.id, fingerprint: plan.fingerprint } },
				);
			}
			case "start": {
				const operation = await coordinatorForSession().start({
					planId: requireValue(params.plan_id, "plan_id"),
				});
				return textResult(`Security scan ${operation.scanId} started as ${operation.operationId}.`, {
					action: params.action,
					operation,
				});
			}
			case "status": {
				const operationId = requireValue(params.operation_id, "operation_id");
				const operation = await coordinatorForSession().status(operationId);
				if (!operation) throw new ToolError(`Unknown security operation: ${operationId}`);
				return textResult(
					`Security scan ${operation.scanId}: ${operation.phase}; ${operation.findingCount} finding(s).`,
					{ action: params.action, operation },
				);
			}
			case "cancel": {
				const operationId = requireValue(params.operation_id, "operation_id");
				const cancelled = await coordinatorForSession().cancel(operationId);
				return textResult(
					cancelled ? `Cancellation requested for ${operationId}.` : `No running operation ${operationId}.`,
					{
						action: params.action,
						cancelled,
						operation: (await coordinatorForSession().status(operationId)) ?? undefined,
					},
				);
			}
			case "cloud_scans": {

View on GitHub (pinned to 9690622007)

Solutions

  1. Verify operation_id against the value returned when the scan was started (start returns 'Security scan <scanId> started as <operationId>').
  2. Run the status check from the same working directory/session where the scan was started.
  3. Re-run action=start with the original plan_id if the operation no longer exists, then poll the new operation_id.
  4. Check for typos or stale ids from earlier runs.

Example fix

// before
await tool.execute(id, { action: "status", operation_id: oldScanId });
// after
await tool.execute(id, { action: "status", operation_id: operationIdFromStartResult });
Defensive patterns

Strategy: validation

Validate before calling

// keep the operationId returned by action=start and verify before polling
const known = new Set<string>(); // add ids from start results
if (!known.has(operationId)) throw new Error(`no local record of operation ${operationId}`);

Try / catch

try { return await tool.execute(id, { action: "status", operation_id }); } catch (e) { if (e instanceof ToolError && e.message.startsWith("Unknown security operation")) { return null; /* treat as expired */ } throw e; }

Prevention

When it happens

Trigger: security_scan with action="status" and an operation_id that was never started, was started in a different cwd/session (different coordinator store), was already pruned, or contains a typo; also after a process restart if the operation was in-memory only.

Common situations: Copy-pasting an operation id from an earlier session or another repository; querying status after the scan finished and was cleaned up; mistaking a scanId for an operationId.

Related errors


AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31). Data as JSON: /api/errors/ad5b32321f2a5b1b. Report an issue: GitHub.