OpenBMB/ChatDev · error · ConfigError
model.input_mode must be 'prompt' or 'messages'
Error message
model.input_mode must be 'prompt' or 'messages'
What it means
The optional 'input_mode' field of an agent's model config could not be mapped to the AgentInputMode enum. Only 'prompt' (single string input) and 'messages' (structured chat messages, the default) are accepted; matching is case-insensitive after stripping.
Source
Thrown at entity/configs/node/agent.py:361
mapping = require_mapping(data, path)
provider = require_str(mapping, "provider", path)
base_url = optional_str(mapping, "base_url", path)
name_value = mapping.get("name")
if isinstance(name_value, str) and name_value.strip():
model_name = name_value.strip()
else:
raise ConfigError("model.name must be a non-empty string", extend_path(path, "name"))
role = optional_str(mapping, "role", path)
api_key = optional_str(mapping, "api_key", path)
params = optional_dict(mapping, "params", path) or {}
raw_input_mode = optional_str(mapping, "input_mode", path)
input_mode = AgentInputMode.MESSAGES
if raw_input_mode:
try:
input_mode = AgentInputMode(raw_input_mode.strip().lower())
except ValueError as exc:
raise ConfigError(
"model.input_mode must be 'prompt' or 'messages'",
extend_path(path, "input_mode"),
) from exc
tooling_cfg: List[ToolingConfig] = []
if "tooling" in mapping and mapping["tooling"] is not None:
raw_tooling = mapping["tooling"]
if not isinstance(raw_tooling, list):
raise ConfigError("tooling must be a list", extend_path(path, "tooling"))
for idx, item in enumerate(raw_tooling):
tooling_cfg.append(
ToolingConfig.from_dict(item, path=extend_path(path, f"tooling[{idx}]"))
)
thinking_cfg = None
if "thinking" in mapping and mapping["thinking"] is not None:
thinking_cfg = ThinkingConfig.from_dict(mapping["thinking"], path=extend_path(path, "thinking"))
View on GitHub (pinned to 4fb2db0ea9)
Solutions
- Set input_mode to exactly 'prompt' or 'messages' (any casing works since it is lowered)
- Omit input_mode entirely if you want the default 'messages' behavior
- Search your config source for the bad literal using the error's path
Example fix
// before
{"input_mode": "chat"}
// after
{"input_mode": "prompt"} Defensive patterns
Strategy: type-guard
Validate before calling
ALLOWED_MODES = {'prompt', 'messages'}
mode = (cfg.get('model', {}).get('input_mode') or 'messages').strip().lower()
if mode not in ALLOWED_MODES:
cfg['model']['input_mode'] = 'messages' Type guard
def valid_input_mode(cfg: dict) -> bool:
m = cfg.get('model', {}).get('input_mode')
return m is None or (isinstance(m, str) and m.strip().lower() in {'prompt', 'messages'}) Try / catch
try:
ModelConfig.from_dict(data, path='agent')
except ConfigError as e:
if 'input_mode' in e.path:
data['model'].pop('input_mode', None) # fall back to default
ModelConfig.from_dict(data, path='agent')
else:
raise Prevention
- Normalize case and strip whitespace before setting input_mode
- Expose only a two-option dropdown in UIs that author agent configs
- Omit the key when unsure — default is 'messages'
When it happens
Trigger: Setting model.input_mode to anything other than 'prompt' or 'messages' (case-insensitive), e.g. 'chat', 'text', 'completion', or a typo like 'promt'. Absent/null input_mode is fine and defaults to MESSAGES.
Common situations: Copy-pasting configs from other agent frameworks that use 'chat'/'text' modes; typos; version changes where old mode names were removed.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- model.name must be a non-empty string
- tooling must be a list
- memories must be a list
- role must be 'user' or 'assistant'
- duration_unit must be one of: {', '.join(valid_units)}
AI-assisted analysis of OpenBMB/ChatDev@4fb2db0ea9 (2026-08-27).
Data as JSON: /api/errors/db837bf42c2e38ca.
Report an issue: GitHub.