can1357/oh-my-pi · error

Security scan model is unavailable: ${plan.model.provider}/$

Error message

Security scan model is unavailable: ${plan.model.provider}/${plan.model.modelId}

What it means

The security scan coordinator needs the model recorded in the scan plan to run the scan session. It first checks the host's active model, then falls back to the model registry lookup; if neither can resolve the provider/modelId pair, it throws. This guards against executing scans with a model that cannot be constructed.

Source

Thrown at packages/coding-agent/src/security/coordinator.ts:592

			);
			if (signal.aborted) throw signal.reason ?? new Error("Security scan cancelled");
			await prepareSecurityOutputDirectory(plan.output, record.snapshot.scanId);
			this.#update(record, "preparing");
			await reportProgress?.("Preparing OMP-native security scan");
			executionTarget = await prepareSecurityExecutionTarget(
				plan,
				store,
				record.snapshot.scanId,
				this.#gitAdapter,
				signal,
			);
			const activeModel = this.#host.activeModel;
			const model =
				activeModel?.provider === plan.model.provider && activeModel.id === plan.model.modelId
					? activeModel
					: this.#host.modelRegistry.find(plan.model.provider, plan.model.modelId);
			if (!model)
				throw new Error(`Security scan model is unavailable: ${plan.model.provider}/${plan.model.modelId}`);
			const sessionsDirectory = path.join(store.projectDirectory, "sessions");
			await fs.mkdir(sessionsDirectory, { recursive: true, mode: 0o700 });
			const sessionManager = SessionManager.create(executionTarget.cwd, sessionsDirectory);
			const publicationTool = createSecurityPublicationTool({
				plan,
				scanId: record.snapshot.scanId,
				store,
				startedAt,
				sessionId: `security:${record.snapshot.scanId}`,
				operationId: record.snapshot.operationId,
				onPublished: async bundle => {
					publishedBundle = bundle;
					record.snapshot.findingCount = bundle.findings.length;
					this.#update(record, "publishing");
				},
			});
			session = await this.#createSession({
				host: this.#host,

View on GitHub (pinned to 9690622007)

Solutions

  1. Check that the provider/model in the plan matches a model configured in the current session (the active model or one in the registry)
  2. Re-generate the security scan plan with the currently active model so plan.model matches this.#host.activeModel
  3. Add the missing provider/model back to the model registry/config, then retry the scan

Example fix

// before: plan holds a stale model
{ "model": { "provider": "anthropic", "modelId": "claude-3-opus-20240229" } }
// after: re-plan with the active model
const plan = await planScan({ model: { provider: host.activeModel.provider, modelId: host.activeModel.id } });
Defensive patterns

Strategy: validation

Validate before calling

const active = host.activeModel;
const model = active?.provider === plan.model.provider && active.id === plan.model.modelId
  ? active
  : host.modelRegistry.find(plan.model.provider, plan.model.modelId);
if (!model) throw new Error(`Plan model unavailable: ${plan.model.provider}/${plan.model.modelId} — re-plan with the active model`);

Type guard

function isModelResolvable(host: { activeModel?: { provider: string; id: string } | null; modelRegistry: { find(p: string, id: string): unknown } }, plan: { model: { provider: string; modelId: string } }): boolean {
  return (host.activeModel?.provider === plan.model.provider && host.activeModel.id === plan.model.modelId) ||
    host.modelRegistry.find(plan.model.provider, plan.model.modelId) != null;
}

Try / catch

try {
  await coordinator.run(plan);
} catch (err) {
  if (err instanceof Error && err.message.startsWith("Security scan model is unavailable")) {
    plan = await replanWithActiveModel(); // regenerate plan against host.activeModel
  } else throw err;
}

Prevention

When it happens

Trigger: Security scan plan references a model (provider/modelId) that is neither the currently active host model nor present in the model registry — e.g. the plan was generated earlier against a model since removed from config, or the registry was built without that provider.

Common situations: Switching/removing a model from opencode config after a scan plan was drafted; typo'd or stale modelId in plan state; provider plugin not loaded so registry lacks the entry; running a persisted/resumed plan after a model catalog change.

Related errors


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