linshenkx/prompt-optimizer · error · RequestConfigError

Model provider metadata cannot be empty

Error message

Model provider metadata cannot be empty

What it means

Thrown by validateModelConfig when the resolved model configuration has no providerMeta or providerMeta.id. The LLM service requires every model config to carry provider metadata (e.g. 'openai', 'anthropic') so it can look up the correct adapter in the registry. Without it, the service cannot route the request to any provider.

Source

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

      }
      if (typeof msg.content !== 'string') {
        throw new RequestConfigError('Message content must be a string');
      }
    });
  }

  /**
   * 验证模型配置
   */
  private validateModelConfig(
    modelConfig: TextModelConfig,
    options: { allowDisabled?: boolean } = {}
  ): void {
    if (!modelConfig) {
      throw new RequestConfigError('Model config cannot be empty');
    }
    if (!modelConfig.providerMeta || !modelConfig.providerMeta.id) {
      throw new RequestConfigError('Model provider metadata cannot be empty');
    }
    if (!modelConfig.modelMeta || !modelConfig.modelMeta.id) {
      throw new RequestConfigError('Model metadata cannot be empty');
    }
    // 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');

View on GitHub (pinned to 3e677b1d9f)

Solutions

  1. Check that the object you pass (or that modelManager resolves) includes providerMeta: { id: 'openai', ... } with a non-empty id
  2. If migrating from a flat provider field, map it: config.providerMeta = { id: config.provider }
  3. Re-save or re-import the model configuration through the current version of the model manager so nested provider metadata is persisted
  4. If you control the config source, add a startup assertion that every model has providerMeta.id before enabling the UI

Example fix

// before
const config: ModelConfig = { modelMeta: { id: 'gpt-4o' }, enabled: true };

// after
const config: ModelConfig = {
  providerMeta: { id: 'openai' },
  modelMeta: { id: 'gpt-4o' },
  enabled: true,
};
Defensive patterns

Strategy: validation

Validate before calling

function hasProviderMeta(c: ModelConfig | undefined | null): boolean {
  return !!c && !!c.providerMeta && !!c.providerMeta.id;
}

Type guard

function isValidModelConfig(c: unknown): c is ModelConfig {
  const m = c as ModelConfig;
  return !!m && !!m.providerMeta?.id && !!m.modelMeta?.id;
}

Try / catch

try { await llm.sendMessageStructured(msgs, 'openai'); } catch (e) { if (e instanceof RequestConfigError && /provider metadata/.test(e.message)) fixModelConfig(); }

Prevention

When it happens

Trigger: Calling sendMessageStructured, sendMessageStream, sendMessageStreamWithTools, or testConnection with a model config whose providerMeta is undefined/null or whose providerMeta.id is falsy (empty string). Typically happens when a manually constructed ModelConfig omits providerMeta, or modelManager.getModel returns a partially hydrated record.

Common situations: Building a ModelConfig object by hand for tests; migrating model config schemas where providerMeta was renamed (e.g. from a flat 'provider' field); stale persisted configs saved by an older version that lack the nested provider metadata; seed/import scripts that only set modelMeta.

Related errors


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