{"record":{"id":"1cc7a724634ce382","repo":"NousResearch/hermes-agent","slug":"per-launch-timeout-is-not-supported-configure-del","errorCode":null,"errorMessage":"Per-launch timeout is not supported; configure delegation timeout explicitly.","messagePattern":"Per-launch timeout is not supported; configure delegation timeout explicitly\\.","errorType":"exception","errorClass":"SubagentLifecycleError","httpStatus":null,"severity":"error","filePath":"agent/subagent_lifecycle.py","lineNumber":507,"sourceCode":"            not isinstance(request, SubagentLaunchRequest)\n            or not isinstance(request.goal, str)\n            or not request.goal.strip()\n            or len(request.goal) > _MAX_GOAL_CHARS\n        ):\n            raise SubagentLifecycleError(\n                \"goal must be a non-empty string of at most 16000 characters.\"\n            )\n        if request.context is not None and (\n            not isinstance(request.context, str)\n            or len(request.context) > _MAX_CONTEXT_CHARS\n        ):\n            raise SubagentLifecycleError(\n                \"context must be a string of at most 32000 characters.\"\n            )\n        if request.role not in {\"leaf\", \"orchestrator\"}:\n            raise SubagentLifecycleError(\"role must be 'leaf' or 'orchestrator'.\")\n        if request.timeout_seconds is not None:\n            raise SubagentLifecycleError(\n                \"Per-launch timeout is not supported; configure delegation timeout explicitly.\"\n            )\n        if request.working_directory is not None:\n            raise SubagentLifecycleError(\n                \"working_directory is not supported because Hermes delegates use isolated task environments.\"\n            )\n        if request.blocked_tools:\n            raise SubagentLifecycleError(\n                \"Per-tool blocking is not supported; use allowed_toolsets. Hermes always blocks unsafe child tools.\"\n            )\n        try:\n            metadata_bytes = len(\n                json.dumps(dict(request.metadata), sort_keys=True).encode()\n            )\n        except (TypeError, ValueError) as exc:\n            raise SubagentLifecycleError(\"metadata must be JSON-serializable.\") from exc\n        if metadata_bytes > _MAX_METADATA_BYTES:\n            raise SubagentLifecycleError(\"metadata exceeds 8192 bytes.\")","sourceCodeStart":489,"sourceCodeEnd":525,"githubUrl":"https://github.com/NousResearch/hermes-agent/blob/c896c09c42910c584c4c7d2325b58c14713ea42c/agent/subagent_lifecycle.py#L489-L525","documentation":"Validation error from SubagentLifecycleManager._validate_request(): per-launch timeouts are deliberately not part of the subagent lifecycle contract. If request.timeout_seconds is not None the launch is rejected with a pointer to the global delegation timeout configuration — child timeouts must be configured at the delegation level, not per launch.","triggerScenarios":"Setting SubagentLaunchRequest(timeout_seconds=300); porting code from an async-subagent API that accepted per-task timeouts; SDK-generated request objects that populate every optional field with a default number instead of None.","commonSituations":"Autofilling serializers (e.g. protobuf/thrift defaults of 0 that become non-None); copying a request template from another tool; trying to bound a risky child individually.","solutions":["Remove timeout_seconds from the request (leave it None) and set the global cap via delegation.child_timeout_seconds in config.yaml.","If you need per-task time bounds, enforce them yourself by polling the child's status and abandoning/ignoring results past a deadline.","Audit request-construction helpers so optional numerics default to None, not 0."],"exampleFix":"# before\nrequest = SubagentLaunchRequest(goal=g, timeout_seconds=120)\n\n# after\n# config.yaml: delegation: child_timeout_seconds: 120\nrequest = SubagentLaunchRequest(goal=g)","handlingStrategy":"validation","validationCode":"request = SubagentLaunchRequest(goal=goal)  # timeout_seconds omitted -> None\n# enforce per-task deadlines yourself:\ndeadline = time.monotonic() + 120","typeGuard":null,"tryCatchPattern":"try:\n    manager.launch(request)\nexcept SubagentLifecycleError as exc:\n    if \"Per-launch timeout\" in str(exc):\n        request = dataclasses.replace(request, timeout_seconds=None)\n        manager.launch(request)\n    else:\n        raise","preventionTips":["Never set timeout_seconds; configure delegation.child_timeout_seconds in config.yaml.","Watch for serializers defaulting numerics to 0 — that is not None and will trip the check.","Implement per-task deadlines by polling status, not via the request field."],"tags":["subagents","delegation","validation","timeout"],"backgroundTag":null,"analyzedSha":"c896c09c42910c584c4c7d2325b58c14713ea42c","analyzedAt":"2026-08-14T17:18:01.089Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}