bytedance/deer-flow · error · PromptConfigurationError
Missing or empty 'messages' key in {path}
Error message
Missing or empty 'messages' key in {path} What it means
PromptConfigurationError from load_prompt_messages: a chat-format YAML prompt file was found, but its top-level 'messages' key is missing, not a list, or an empty list. The deermem prompt loader requires chat templates to carry format: 'chat' plus a non-empty messages list of {role, content} entries.
Source
Thrown at backend/packages/harness/deerflow/agents/memory/backends/deermem/deermem/core/prompt.py:166
return _render_messages(raw_templates, variables, source_path)
base = Path(prompts_dir) if prompts_dir else _PROMPTS_DEFAULT_DIR
candidates: list[Path] = [base / f"{name}.chat.yaml"]
if agent_name:
candidates.insert(0, base / agent_name / f"{name}.chat.yaml")
for path in candidates:
if path.is_file():
try:
data = yaml.safe_load(path.read_text(encoding="utf-8"))
except yaml.YAMLError as e:
raise PromptConfigurationError(f"Invalid YAML in {path}: {e}") from e
data = data or {}
fmt = data.get("format", "chat")
if fmt != "chat":
raise PromptConfigurationError(f"Expected format='chat' in {path}, got {fmt!r}; use load_prompt() for text-format templates")
msg_list = data.get("messages")
if not isinstance(msg_list, list) or not msg_list:
raise PromptConfigurationError(f"Missing or empty 'messages' key in {path}")
raw_templates: list[dict[str, str]] = []
for msg in msg_list:
role = msg.get("role", "user")
content = msg.get("content", "")
if not isinstance(content, str):
content = str(content)
raw_templates.append({"role": role, "content": content})
_CHAT_TEMPLATE_CACHE[cache_key] = (raw_templates, str(path))
return _render_messages(raw_templates, variables, str(path))
searched = ", ".join(str(c) for c in candidates)
raise FileNotFoundError(f"chat prompt template not found: {name} (searched: {searched})")
# Module-level aliases for the injected text sections (staleness_review /
# consolidation / fact_extraction). Each loads its bundled yaml template once
# at import. ``memory_update`` is NOT here -- it uses the chat form via
# :func:`load_prompt_messages` (system/user split, mirroring the lead agent's
# static system prompt).View on GitHub (pinned to 1dd6ba1acb)
Solutions
- Open the named YAML file and add a non-empty messages list of role/content entries.
- If the template is meant to be plain text, keep format as text and use load_prompt() instead of load_prompt_messages().
- Validate prompt YAML with a schema check in CI (format in {chat,text}; chat requires non-empty list of messages).
- Restore the file from git history if a bad edit truncated it.
Example fix
# before (broken)
format: chat
# after
format: chat
messages:
- role: system
content: "You manage long-term memory."
- role: user
content: "{{ text }}" Defensive patterns
Strategy: validation
Validate before calling
import yaml
def validate_chat_prompt(path):
data = yaml.safe_load(path.read_text()) or {}
msgs = data.get('messages')
assert data.get('format') == 'chat', 'format must be chat'
assert isinstance(msgs, list) and msgs, 'messages must be a non-empty list'
assert all(isinstance(m.get('content'), (str,)) for m in msgs) Type guard
def is_chat_prompt(data) -> bool:
return (
isinstance(data, dict)
and data.get('format') == 'chat'
and isinstance(data.get('messages'), list)
and len(data['messages']) > 0
) Try / catch
try:
msgs = load_prompt_messages('memory_update')
except PromptConfigurationError as e:
raise RuntimeError(f'prompt template misconfigured: {e}; fix the YAML messages block') from e Prevention
- Lint all bundled prompt YAML in CI (format + messages shape).
- Use the chat template only for chat prompts; text templates go through load_prompt().
- Template unit tests that render every bundled prompt catch broken files before deploy.
When it happens
Trigger: load_prompt_messages(name) resolves a YAML file whose content is, e.g., a plain string template, has only 'format: chat' with no messages, messages: {} (dict not list), or messages: [].
Common situations: A text-format template mistakenly given format: 'chat'; hand-edited prompt YAML that dropped the messages block; a template truncated by a merge conflict; switching a prompt from text to chat form without restructuring the YAML.
Related errors
- chat prompt template not found: {name} (searched: {searched}
- guaranteed_categories must be an iterable of strings, not a
- unsupported FTS5 retrieval mode: {mode}
- Honcho backend: {key}[{k!r}] has an empty value; remove the
- mem0 backend_config has unknown keys: {sorted(unknown)}
AI-assisted analysis of bytedance/deer-flow@1dd6ba1acb (2026-08-14).
Data as JSON: /api/errors/c1a8bf35e38fe54e.
Report an issue: GitHub.