FoundationAgents/MetaGPT · error · ValueError

Missing fields: {missing_fields}

Error message

Missing fields: {missing_fields}

What it means

MetaGPT's count_message_tokens() estimates Chat Completion prompt size as encoded text plus model-specific per-message/per-name overhead. It implements that overhead only for an explicit set of OpenAI model IDs, the exact aliases gpt-3.5-turbo and gpt-4, the special open-llm-model value, and models whose name contains claude; every other model reaches the else branch and raises NotImplementedError. The preceding tiktoken fallback only chooses an encoding and does not make an unknown model supported.

Source

Thrown at metagpt/actions/action_node.py:262

        return {} if exclude and self.key in exclude else self._get_self_mapping()

    @classmethod
    @register_action_outcls
    def create_model_class(cls, class_name: str, mapping: Dict[str, Tuple[Type, Any]]):
        """基于pydantic v2的模型动态生成,用来检验结果类型正确性"""

        def check_fields(cls, values):
            all_fields = set(mapping.keys())
            required_fields = set()
            for k, v in mapping.items():
                type_v, field_info = v
                if ActionNode.is_optional_type(type_v):
                    continue
                required_fields.add(k)

            missing_fields = required_fields - set(values.keys())
            if missing_fields:
                raise ValueError(f"Missing fields: {missing_fields}")

            unrecognized_fields = set(values.keys()) - all_fields
            if unrecognized_fields:
                logger.warning(f"Unrecognized fields: {unrecognized_fields}")
            return values

        validators = {"check_missing_fields_validator": model_validator(mode="before")(check_fields)}

        new_fields = {}
        for field_name, field_value in mapping.items():
            if isinstance(field_value, dict):
                # 对于嵌套结构,递归创建模型类
                nested_class_name = f"{class_name}_{field_name}"
                nested_class = cls.create_model_class(nested_class_name, field_value)
                new_fields[field_name] = (nested_class, ...)
            else:
                new_fields[field_name] = field_value

View on GitHub (pinned to 11cdf466d0)

Solutions

  1. If you use a custom or deployment model name, set llm.pricing_plan in config2.yaml to an exact supported published model with compatible tokenization (for example gpt-4o-mini); OpenAIGPT uses pricing_plan for usage calculation.
  2. If you intended to use a supported model, correct llm.model to an exact ID from the table, such as gpt-4o-mini-2024-07-18, gpt-4-turbo, gpt-4-0613, or gpt-3.5-turbo-0125; only the exact aliases gpt-3.5-turbo and gpt-4 are normalized.
  3. Upgrade MetaGPT/token_counter.py to a release whose model list includes your model, or patch the local set if you maintain a fork.
  4. For direct calls, catch NotImplementedError and count with a supported model with compatible encoding, or encode the concatenated message text with tiktoken yourself as an explicit approximation.
  5. If accurate usage accounting is not needed, set llm.calc_usage: false; this avoids the _calc_usage warning but does not make count_message_tokens support the model.

Example fix

# before (config2.yaml)
llm:
  api_type: openai
  base_url: https://your-openai-compatible-endpoint/v1
  model: my-qwen-deployment

# after: keep the served model, but count usage with a supported pricing plan
llm:
  api_type: openai
  base_url: https://your-openai-compatible-endpoint/v1
  model: my-qwen-deployment
  pricing_plan: gpt-4o-mini
Defensive patterns

Strategy: validation

Validate before calling

from metagpt.utils.token_counter import count_message_tokens

_MESSAGE_TOKEN_MODELS = {
    "gpt-3.5-turbo-0613", "gpt-3.5-turbo-16k-0613", "gpt-35-turbo",
    "gpt-35-turbo-16k", "gpt-3.5-turbo-16k", "gpt-3.5-turbo-1106",
    "gpt-3.5-turbo-0125", "gpt-3.5-turbo-0301", "gpt-3.5-turbo",
    "gpt-4-0314", "gpt-4-32k-0314", "gpt-4-0613", "gpt-4-32k-0613",
    "gpt-4-turbo", "gpt-4-turbo-preview", "gpt-4-0125-preview",
    "gpt-4-1106-preview", "gpt-4-vision-preview", "gpt-4-1106-vision-preview",
    "gpt-4o", "gpt-4o-2024-05-13", "gpt-4o-2024-08-06",
    "gpt-4o-mini", "gpt-4o-mini-2024-07-18", "o1-preview",
    "o1-preview-2024-09-12", "o1-mini", "o1-mini-2024-09-12",
    "gpt-4", "open-llm-model",
}

def supports_message_token_count(model: str) -> bool:
    return "claude" in model or model in _MESSAGE_TOKEN_MODELS

assert supports_message_token_count(model)
num_tokens = count_message_tokens(messages, model)

Type guard

from typing import TypeGuard

def is_countable_message_model(model: object) -> TypeGuard[str]:
    return isinstance(model, str) and (
        "claude" in model or model in _MESSAGE_TOKEN_MODELS
    )

if is_countable_message_model(model):
    num_tokens = count_message_tokens(messages, model)

Try / catch

try:
    num_tokens = count_message_tokens(messages, model)
except NotImplementedError as exc:
    fallback = "gpt-4o-mini"  # choose a model with compatible encoding explicitly
    logger.warning("%s; retrying token estimate with %s", exc, fallback)
    num_tokens = count_message_tokens(messages, fallback)

Prevention

When it happens

Trigger: Calling metagpt.utils.token_counter.count_message_tokens(messages, model) directly with a model outside the supported set, such as invalid_model, a typo such as gpt-4o-mini-2024-07-18-typo, or a newer/custom name such as gpt-4.1, o3-mini, qwen..., or deepseek-chat. In OpenAIGPT, _calc_usage() calls it with config.pricing_plan or self.model when calc_usage is true; that call site catches the exception and logs 'usage calculation failed'. OpenAIGPT.count_tokens() calls it with self.model and falls back to the rough BaseLLM heuristic on any exception. get_max_completion_tokens() can also reach it when a model exists in TOKEN_MAX but not in this overhead table.

Common situations: Using an OpenAI-compatible endpoint with a provider-specific model or deployment name and no pricing_plan; adopting a newly released OpenAI model with an older MetaGPT release; Azure deployment names being used where a published model name is expected; typos in config2.yaml llm.model; direct use of token_counter in application code for cost or context-window checks.

Related errors


AI-assisted analysis of FoundationAgents/MetaGPT@11cdf466d0 (2026-08-14). Data as JSON: /api/errors/35eba8350c0059d0. Report an issue: GitHub.