{"record":{"id":"59a58975d46b47a4","repo":"can1357/oh-my-pi","slug":"model-options-model-not-found-59a589","errorCode":null,"errorMessage":"Model \"${options.model}\" not found","messagePattern":"Model \"(.+?)\" not found","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/compress/session.ts","lineNumber":39,"sourceCode":"}\n\n/** Resolve the requested model and open a session restricted to the two protocol tools. */\nexport async function createCompressSession(options: {\n\tcwd?: string;\n\tmodel?: string;\n\tprotocol: CompressProtocol;\n\t/** Distinct per concurrent session; agent ids must be unique within a process. */\n\tagentId?: string;\n}): Promise<CompressSession> {\n\tconst cwd = options.cwd ?? getProjectDir();\n\tconst [settings, authStorage] = await Promise.all([Settings.init({ cwd }), discoverAuthStorage()]);\n\tconst modelRegistry = new ModelRegistry(authStorage);\n\tawait modelRegistry.refresh();\n\t// An absent selector means \"whatever the session is configured to use\", which\n\t// resolveCliModel reports as a model-less, error-less result.\n\tconst resolved = options.model ? resolveCliModel({ cliModel: options.model, modelRegistry, settings }) : undefined;\n\tif (resolved && (resolved.error || !resolved.model)) {\n\t\tthrow new Error(resolved.error ?? `Model \"${options.model}\" not found`);\n\t}\n\tconst { session } = await createAgentSession({\n\t\tcwd,\n\t\tsettings,\n\t\tauthStorage,\n\t\tmodelRegistry,\n\t\t...(resolved?.model ? { model: resolved.model } : {}),\n\t\tcustomTools: [options.protocol.rewriteTool(), options.protocol.approveTool()],\n\t\ttoolNames: [\"rewrite\", \"approve\"],\n\t\trestrictToolNames: true,\n\t\tallowRestrictedCustomTools: true,\n\t\t// Replace the default blocks outright: a compressor needs its own contract, not\n\t\t// the coding-agent workflow. Every discovery source below defaults to ON when\n\t\t// omitted, and each one would inject instruction-shaped project text into a\n\t\t// session whose only legitimate input is the source document.\n\t\tsystemPrompt: [systemPrompt.trim()],\n\t\tskills: [],\n\t\trules: [],","sourceCodeStart":21,"sourceCodeEnd":57,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/compress/session.ts#L21-L57","documentation":"`createCompressSession()` resolves the user-supplied model selector through `resolveCliModel` against a freshly built `ModelRegistry`; when resolution returns an error or no model, this Error is thrown naming the selector. The compress run cannot start without a concrete model because token metrics and generation both depend on it.","triggerScenarios":"Passing `options.model` as a selector string that matches no model in the registry — e.g. a misspelled id (`\"claude-4-sonnet\"`), a deprecated/removed model id, or a provider whose auth/catalog entries are absent after `modelRegistry.refresh()`.","commonSituations":"Typo in a CLI `--model` flag or config file; model renamed upstream so an old pinned id no longer resolves; missing provider API keys so the model is filtered out of the registry; offline catalog refresh.","solutions":["Run with a valid selector — check available ids (e.g. `omp models` / the model registry listing) and fix the spelling","Omit `options.model` entirely so the session uses whatever model the settings configure by default","Verify provider auth is configured so the intended model appears in the refreshed registry"],"exampleFix":"// before\nawait createCompressSession({ model: \"claude-4-sonnet\", ... }); // not found\n// after\nawait createCompressSession({ model: \"anthropic:claude-sonnet-4\", ... }); // or omit model","handlingStrategy":"try-catch","validationCode":"const registry = new ModelRegistry(authStorage);\nawait registry.refresh();\nconst resolved = options.model ? resolveCliModel({ cliModel: options.model, modelRegistry: registry, settings }) : undefined;\nif (resolved?.error || resolved?.model === undefined) {\n  // surface resolved?.error and stop before creating the session\n}","typeGuard":"function isResolvableModel(r: { error?: string; model?: unknown }): r is { error?: undefined; model: NonNullable<typeof r.model> } {\n  return !r.error && r.model != null;\n}","tryCatchPattern":"try {\n  await createCompressSession(options);\n} catch (err) {\n  if (err instanceof Error && /^Model \".*\" not found$/.test(err.message)) {\n    // fall back to settings default (omit options.model) or prompt the user for a valid id\n  } else throw err;\n}","preventionTips":["Validate the `--model` selector against the registry listing before launching","Prefer omitting `options.model` to inherit the configured default","Keep provider auth configured so intended models survive registry refresh","Update pinned model ids after upstream renames/deprecations"],"tags":["configuration","model-resolution","cli"],"backgroundTag":"model-not-found","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}