FoundationAgents/MetaGPT · error · RuntimeError
use `review` after `fill`
Error message
use `review` after `fill`
What it means
YamlModelWithoutDefault is a Pydantic base class meant to reject configuration files that still contain template placeholders. Its mode='before' model_validator scans the incoming values container for any element containing the substring 'YOUR' and raises ValueError before field validation. In this checkout the class is not used by Config itself (Config inherits YamlModel), so the error comes from a subclass of YamlModelWithoutDefault or equivalent direct validation. With a normal dict, Python iterates keys, so the current check primarily tests top-level field/map keys rather than nested values.
Source
Thrown at metagpt/actions/action_node.py:737
# generate review comments
if review_mode == ReviewMode.HUMAN:
review_comments = await self.human_review()
else:
review_comments = await self.auto_review()
if not review_comments:
logger.warning("There are no review comments")
return review_comments
async def review(self, strgy: str = "simple", review_mode: ReviewMode = ReviewMode.AUTO):
"""only give the review comment of each exist and mismatch key
:param strgy: simple/complex
- simple: run only once
- complex: run each node
"""
if not hasattr(self, "llm"):
raise RuntimeError("use `review` after `fill`")
assert review_mode in ReviewMode
assert self.instruct_content, 'review only support with `schema != "raw"`'
if strgy == "simple":
review_comments = await self.simple_review(review_mode)
elif strgy == "complex":
# review each child node one-by-one
review_comments = {}
for _, child in self.children.items():
child_review_comment = await child.simple_review(review_mode)
review_comments.update(child_review_comment)
return review_comments
async def human_revise(self) -> dict[str, str]:
review_contents = HumanInteraction().interact_with_instruct_content(
instruct_content=self.instruct_content, mapping=self.get_mapping(mode="auto"), interact_type="revise"
)View on GitHub (pinned to 11cdf466d0)
Solutions
- Identify the file actually loaded using MetaGPT's priority order, especially ~/.metagpt/config2.yaml versus METAGPT_ROOT/config/config2.yaml, and open that exact file.
- Replace every remaining YOUR_* placeholder with a real value; never commit the completed file or paste the secret into chat/logs.
- For example/tool blocks you do not use, delete or comment out the entire block instead of leaving YOUR_* values or keys.
- In multi-model maps, replace placeholder keys such as YOUR_MODEL_NAME_1 with real model names and provide their api_key/base_url entries.
- In CI/Docker, verify the mounted config2.yaml exists at the expected path and contains no template text before starting MetaGPT.
Example fix
# before (~/.metagpt/config2.yaml) llm: api_type: openai base_url: https://api.openai.com/v1 api_key: "YOUR_API_KEY" # after: put the real key in this local, untracked file llm: api_type: openai base_url: https://api.openai.com/v1 api_key: "sk-REDACTED-REAL-KEY"
Defensive patterns
Strategy: validation
Validate before calling
from pathlib import Path
import yaml
def has_yaml_placeholder(node) -> bool:
if isinstance(node, str):
return "YOUR" in node
if isinstance(node, dict):
return any("YOUR" in str(k) or has_yaml_placeholder(v) for k, v in node.items())
if isinstance(node, list):
return any(has_yaml_placeholder(item) for item in node)
return False
path = Path.home() / ".metagpt/config2.yaml"
raw = yaml.safe_load(path.read_text(encoding="utf-8"))
if has_yaml_placeholder(raw):
raise RuntimeError(f"Replace every YOUR_* placeholder in {path} before loading it")
model = YourYamlModelWithoutDefault.from_yaml_file(path) Type guard
from typing import Any, TypeGuard
def is_placeholder_free_config(data: object) -> TypeGuard[dict[str, Any]]:
return isinstance(data, dict) and not has_yaml_placeholder(data)
raw = yaml.safe_load(path.read_text(encoding="utf-8"))
if not is_placeholder_free_config(raw):
raise RuntimeError("config2.yaml still contains YOUR_* placeholders") Try / catch
from pydantic import ValidationError
try:
model = YourYamlModelWithoutDefault.model_validate(raw)
except ValidationError as exc:
if "Please set your config in config2.yaml" in str(exc):
raise RuntimeError("Unconfigured MetaGPT config: replace all YOUR_* placeholders") from exc
raise Prevention
- After copying an example config, search it for 'YOUR' before running MetaGPT: grep -n 'YOUR' ~/.metagpt/config2.yaml.
- Keep config2.yaml local and untracked; load real secrets from your secret manager when generating it.
- Delete unused example sections instead of leaving placeholder-filled blocks in the YAML.
- In CI, add a startup check that fails the job when the mounted config2.yaml contains template text.
- Remember the load priority: ~/.metagpt/config2.yaml overrides config/config2.yaml, so edit the file actually loaded.
When it happens
Trigger: Calling YourYamlModelWithoutDefault.from_yaml_file(path), YourYamlModelWithoutDefault.model_validate(data), or its constructor with input containing a top-level element whose text contains 'YOUR', such as a key named YOUR_MODEL_NAME_1. It is intended to trigger when config2.yaml or a copied example still has placeholders such as YOUR_API_KEY, YOUR_BASE_URL, or YOUR_PROXY; a nested api_key: YOUR_API_KEY is what users usually intend it to catch, though the implementation's top-level scan can miss it depending on the input shape. Pydantic normally wraps the raised ValueError in a ValidationError.
Common situations: Copying config/config2.example.yaml or running metagpt --init-config and never replacing the YOUR_* placeholders; editing the repository config/config2.yaml while MetaGPT actually loads ~/.metagpt/config2.yaml; CI or Docker runs where the intended config2.yaml secret was not mounted; copied multi-model examples that leave YOUR_MODEL_NAME_1/YOUR_MODEL_NAME_2 keys in place; retaining unused example tool sections filled with placeholders.
Related errors
- please check MilvusConnection, uri must be set.
- please check QdrantConnection.
- Configuration file '{FILE_NAME}' not found in settings direc
- Error parsing YAML file '{FILE_NAME}': {str(e)}
- Missing fields: {missing_fields}
AI-assisted analysis of FoundationAgents/MetaGPT@11cdf466d0 (2026-08-14).
Data as JSON: /api/errors/015c25666dea67f8.
Report an issue: GitHub.