NousResearch/hermes-agent · error · SubagentLifecycleError
context must be a string of at most 32000 characters.
Error message
context must be a string of at most 32000 characters.
What it means
Validation error from SubagentLifecycleManager._validate_request(): when context is provided on SubagentLaunchRequest it must be a string of at most _MAX_CONTEXT_CHARS (32000) characters. None is allowed (no context); anything non-string or oversized is rejected before launch.
Source
Thrown at agent/subagent_lifecycle.py:501
value = f"{subagent_id}|{parent_session_id or ''}|{created_at:.6f}".encode()
return hmac.new(_SECRET, value, hashlib.sha256).hexdigest()
@staticmethod
def _validate_request(request: SubagentLaunchRequest, parent: Any) -> None:
if (
not isinstance(request, SubagentLaunchRequest)
or not isinstance(request.goal, str)
or not request.goal.strip()
or len(request.goal) > _MAX_GOAL_CHARS
):
raise SubagentLifecycleError(
"goal must be a non-empty string of at most 16000 characters."
)
if request.context is not None and (
not isinstance(request.context, str)
or len(request.context) > _MAX_CONTEXT_CHARS
):
raise SubagentLifecycleError(
"context must be a string of at most 32000 characters."
)
if request.role not in {"leaf", "orchestrator"}:
raise SubagentLifecycleError("role must be 'leaf' or 'orchestrator'.")
if request.timeout_seconds is not None:
raise SubagentLifecycleError(
"Per-launch timeout is not supported; configure delegation timeout explicitly."
)
if request.working_directory is not None:
raise SubagentLifecycleError(
"working_directory is not supported because Hermes delegates use isolated task environments."
)
if request.blocked_tools:
raise SubagentLifecycleError(
"Per-tool blocking is not supported; use allowed_toolsets. Hermes always blocks unsafe child tools."
)
try:
metadata_bytes = len(View on GitHub (pinned to c896c09c42)
Solutions
- Serialize structured context with json.dumps(...) or summarize it to text before passing.
- If context exceeds 32000 chars, write it to a file and reference the path in the goal, or truncate/compress it.
- Keep context as None when there is nothing to add.
Example fix
# before
request = SubagentLaunchRequest(goal=g, context={"repo": "x", "logs": logs_text})
# after
import json
ctx = json.dumps({"repo": "x"}) + "\n" + logs_text[-20000:]
request = SubagentLaunchRequest(goal=g, context=ctx) Defensive patterns
Strategy: validation
Validate before calling
MAX_CTX = 32000
if context is not None:
assert isinstance(context, str) and len(context) <= MAX_CTX
request = SubagentLaunchRequest(goal=goal, context=context) Type guard
def is_valid_context(value: object) -> bool:
return value is None or (isinstance(value, str) and len(value) <= 32000) Try / catch
try:
manager.launch(request)
except SubagentLifecycleError as exc:
if "context must be" in str(exc):
request = dataclasses.replace(request, context=context[:32000])
manager.launch(request)
else:
raise Prevention
- json.dumps structured context before passing it.
- Keep big documents out-of-band; pass a path or summary.
- Remember the split: goal 16000, context 32000.
When it happens
Trigger: Passing context as a dict/list (un-serialized payload), a bytes object, or a string over 32000 chars; stuffing whole file contents or transcripts into context.
Common situations: Mapping an API's structured context object straight onto the field without json.dumps; attaching a large log excerpt or document body as context; mixing up goal and context limits (16000 vs 32000).
Related errors
- goal must be a non-empty string of at most 16000 characters.
- parent_session_id does not match the active session.
- role must be 'leaf' or 'orchestrator'.
- Per-launch timeout is not supported; configure delegation ti
- working_directory is not supported because Hermes delegates
AI-assisted analysis of NousResearch/hermes-agent@c896c09c42 (2026-08-14).
Data as JSON: /api/errors/bc3d16cd2d5dfdf7.
Report an issue: GitHub.