langchain-ai/deepagents · error · TypeError
system_prompt must be str or None, got {type(system_prompt).
Error message
system_prompt must be str or None, got {type(system_prompt).__name__} What it means
The `compact_conversation` tool middleware accepts an optional `system_prompt` that must be a `str` or `None`. Any other type (dict, bytes, list, etc.) is rejected with `TypeError` in `__init__`, guarding against silently coercing invalid prompt values.
Source
Thrown at libs/deepagents/deepagents/middleware/summarization.py:1858
system_prompt: str | None = None,
) -> None:
"""Initialize with a reference to the summarization middleware.
Args:
summarization: The `SummarizationMiddleware` instance whose
summarization engine this tool will delegate to.
system_prompt: System-prompt fragment nudging the model to call
`compact_conversation`. Pass `None` to skip appending the
nudge entirely (the tool remains registered and callable
but the model is unlikely to discover it without an
external mention).
Raises:
TypeError: If `system_prompt` is not `str` or `None`.
"""
if system_prompt is not None and not isinstance(system_prompt, str):
msg = f"system_prompt must be str or None, got {type(system_prompt).__name__}"
raise TypeError(msg)
self._summarization = summarization
self.system_prompt = system_prompt
self.tools: list[BaseTool] = [self._create_compact_tool()]
def _create_compact_tool(self) -> BaseTool:
"""Create the `compact_conversation` structured tool.
Returns:
A `StructuredTool` with both sync and async implementations.
"""
from langchain_core.tools import StructuredTool # noqa: PLC0415
mw = self
def sync_compact(runtime: ToolRuntime) -> Command:
return mw._run_compact(runtime)
async def async_compact(runtime: ToolRuntime) -> Command:View on GitHub (pinned to a1af029e6e)
Solutions
- Pass a plain string (or omit for the default)
- Convert structured prompt configs to a string before construction (join sections)
- Validate config-loaded prompt values are strings
Example fix
// before
CompactTool(summarization=mw, system_prompt={"intro": "...", "rules": "..."})
// after
CompactTool(summarization=mw, system_prompt="intro...\nrules...") Defensive patterns
Strategy: type-guard
Validate before calling
if system_prompt is not None and not isinstance(system_prompt, str):
system_prompt = "\n".join(str(p) for p in system_prompt.values()) if isinstance(system_prompt, dict) else str(system_prompt) Type guard
def is_str_or_none(v: object) -> bool:
return v is None or isinstance(v, str) Try / catch
try:
tool_mw = CompactTool(summarization=mw, system_prompt=prompt)
except TypeError as e:
if "system_prompt" in str(e):
logger.error("system_prompt must be str or None, got %r", type(prompt))
raise Prevention
- Coerce prompt configs to strings right after loading YAML/JSON
- Type-annotate `system_prompt: str | None` in wrapper functions
- Unit-test config loading to assert prompt fields deserialize as strings
When it happens
Trigger: Constructing the compact/summarization tool middleware with `system_prompt` set to a non-string value, e.g. a dict of prompt parts or a `None`-like sentinel object.
Common situations: Loading prompts from YAML/JSON where they deserialize to dicts; concatenating prompt fragments into a list; forgetting to `.join()` or `str()` a computed value.
Understand the failure class
Background: "Wrong argument type", "must be a string", "expected Array or Prism::Scope": TypeError and ArgumentError when a library receives a value of the wrong type — this error's family across 28 libraries.
Related errors
- `history_path_prefix` was removed in deepagents 0.7. Configu
- `create_summarization_middleware` expects `model` to be a `B
- Expected UserPromptSubmitDecision, got {type(decision).__nam
- Expected PreCompactDecision, got {type(decision).__name__}
- Expected PermissionRequestDecision, got {type(decision).__na
AI-assisted analysis of langchain-ai/deepagents@a1af029e6e (2026-08-29).
Data as JSON: /api/errors/50dfadc6ea693fa3.
Report an issue: GitHub.