linshenkx/prompt-optimizer · error · RequestConfigError

Model ${provider} not found

Error message

Model ${provider} not found

What it means

Thrown by sendMessageStructured when modelManager.getModel(provider) resolves to nothing. The provider string is accepted as non-empty but no model configuration with that id exists, so the service cannot build a request. Distinguish from 'Model provider cannot be empty': here the id was provided but unknown.

Source

Thrown at packages/core/src/services/llm/service.ts:90

    // Default behavior: disabled models cannot be used for normal requests.
    // Connection testing is allowed to bypass this check (align with image model test behavior).
    if (!options.allowDisabled && !modelConfig.enabled) {
      throw new RequestConfigError('Model is not enabled');
    }
  }

  /**
   * 发送消息(结构化格式)
   */
  async sendMessageStructured(messages: Message[], provider: string): Promise<LLMResponse> {
    try {
      if (!provider) {
        throw new RequestConfigError('Model provider cannot be empty');
      }

      const modelConfig = await this.modelManager.getModel(provider);
      if (!modelConfig) {
        throw new RequestConfigError(`Model ${provider} not found`);
      }

      this.validateModelConfig(modelConfig);
      this.validateMessages(messages);

      // 通过 Registry 获取 Adapter
      const adapter = this.registry.getAdapter(modelConfig.providerMeta.id);

      const runtimeConfig = this.prepareRuntimeConfig(modelConfig);

      // 使用 Adapter 发送消息
      return await adapter.sendMessage(messages, runtimeConfig);

    } catch (error: any) {
      if (error instanceof RequestConfigError || error instanceof APIError) {
        throw error;
      }
      throw new APIError(`Failed to send message: ${error.message}`);

View on GitHub (pinned to 3e677b1d9f)

Solutions

  1. List registered models (e.g. modelManager.listModels()) and verify the exact id exists, including casing
  2. If configs load async, await model manager initialization before sending messages
  3. Register/add the model config for that provider id, or switch the call to an id that exists

Example fix

// before
await llm.sendMessageStructured(msgs, 'gpt4'); // not registered

// after
const models = await modelManager.listModels();
const target = models.find(m => m.providerMeta.id === 'openai');
await llm.sendMessageStructured(msgs, target!.providerMeta.id);
Defensive patterns

Strategy: validation

Validate before calling

const cfg = await modelManager.getModel(provider);
if (!cfg) throw new Error(`Provider "${provider}" is not registered. Available: ${(await modelManager.listModels()).map(m => m.providerMeta.id).join(', ')}`);

Type guard

async function providerExists(pm: ModelManager, id: string): Promise<boolean> { return !!(await pm.getModel(id)); }

Try / catch

catch (e) { if (e instanceof RequestConfigError && /not found/.test(e.message)) { offerModelSelection(); } }

Prevention

When it happens

Trigger: Calling sendMessageStructured(messages, 'some-provider-id') where no model config with that id has been registered/added to the model manager. Also possible if configs are stored asynchronously and not yet loaded when the call is made.

Common situations: Typos or case mismatch in the provider id ('OpenAI' vs 'openai'); referencing a model the user deleted; a config store that hasn't finished initializing (race at app startup); profile or workspace switch that cleared model configs.

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


AI-assisted analysis of linshenkx/prompt-optimizer@3e677b1d9f (2026-08-27). Data as JSON: /api/errors/7657af87f003e583. Report an issue: GitHub.