{"record":{"id":"79214d9312143d48","repo":"langchain-ai/deepagents","slug":"message","errorCode":null,"errorMessage":"{message}","messagePattern":"\\{message\\}","errorType":"exception","errorClass":"HITLIterationLimitError","httpStatus":null,"severity":"error","filePath":"libs/code/deepagents_code/client/non_interactive.py","lineNumber":138,"sourceCode":"        HookNoticeCallback,\n        HookNoticeSeverity,\n    )\n    from deepagents_code.hooks.transcript import TranscriptRecorder\n\nlogger = logging.getLogger(__name__)\n\n\nclass HITLIterationLimitError(RuntimeError):\n    \"\"\"Raised when the HITL interrupt loop exceeds `_MAX_HITL_ITERATIONS` rounds.\"\"\"\n\n\ndef _raise_hitl_iteration_limit(message: str) -> NoReturn:\n    \"\"\"Raise the bounded-turn failure outside the stream-control try block.\n\n    Raises:\n        HITLIterationLimitError: Always, with the supplied message.\n    \"\"\"\n    raise HITLIterationLimitError(message)\n\n\ndef _raise_client_hook_stop(message: str) -> NoReturn:\n    from deepagents_code.hooks.client_lifecycle import ClientHookStopError\n\n    raise ClientHookStopError(message)\n\n\n_HITL_REQUEST_ADAPTER = TypeAdapter(HITLRequest)\n\n_STREAM_CHUNK_LENGTH = 3\n\"\"\"Expected element counts for the tuples emitted by agent.astream.\n\nStream chunks are 3-tuples: (namespace, stream_mode, data).\n\"\"\"\n\n_MESSAGE_DATA_LENGTH = 2\n\"\"\"Message-mode data is a 2-tuple: (message_obj, metadata).\"\"\"","sourceCodeStart":120,"sourceCodeEnd":156,"githubUrl":"https://github.com/langchain-ai/deepagents/blob/a1af029e6e73cb17c36bff823d227747b28e91e1/libs/code/deepagents_code/client/non_interactive.py#L120-L156","documentation":"`_raise_hitl_iteration_limit` raises `HITLIterationLimitError` when the headless (non-interactive) agent loop exceeds its bounded number of human-in-the-loop turns. Because headless mode has no human to keep answering permission prompts, the loop is capped to prevent an infinite permission request/response cycle; exceeding the cap aborts the run with this error.","triggerScenarios":"Calling `run_non_interactive` with a task that repeatedly triggers HITL permission requests (e.g. many tool calls requiring approval from the allow-list resolution) such that `_run_agent_loop` consumes the maximum allowed HITL iterations without completing.","commonSituations":"Automated CI/headless runs where a shell command or file edit is not covered by `shell.allow_list` or other permission rules, causing repeated permission interrupts; misconfigured permission rules that force every tool call into the HITL path; tasks that legitimately need more approval rounds than the configured limit.","solutions":["Adjust the permission configuration (e.g. `shell.allow_list`) so recurring tool calls are auto-approved and stop consuming HITL turns.","Raise the HITL iteration limit option if the task genuinely needs more approval rounds.","Re-run non-interactively with a permission mode that auto-allows the tools the task needs (e.g. accept-edits/bypass where policy permits).","Split the task into smaller runs so each stays within the turn budget."],"exampleFix":"// before: command not allow-listed, consumes HITL turns each run\nsubprocess.run([\"make\", \"lint\"])\n// after: pre-approve in config so no HITL turns are used\n# config: shell.allow_list = [\"make *\"]\nsubprocess.run([\"make\", \"lint\"])","handlingStrategy":"validation","validationCode":"from deepagents_code.config_manifest import get_option\nfrom deepagents_code.configuration.resolver import get_config_resolver\noption = get_option(\"shell.allow_list\")\nresolved = get_config_resolver().get(option)\n# ensure the commands your task needs are allow-listed before the run\nassert resolved.value, \"shell.allow_list must cover task commands to avoid HITL turn exhaustion\"","typeGuard":null,"tryCatchPattern":"from deepagents_code.client.non_interactive import HITLIterationLimitError\ntry:\n    run_non_interactive(task)\nexcept HITLIterationLimitError as exc:\n    print(f\"hitl budget exhausted: {exc}\")  # loosen permissions or raise limit and retry","preventionTips":["Keep `shell.allow_list` aligned with every command the automated task will run","Monitor how many HITL turns a task consumes and raise the limit before running long jobs","Prefer headless permission modes that auto-approve expected tool calls"],"tags":["headless","hitl","iteration-limit","permissions"],"backgroundTag":"hitl-iteration-limit-exceeded","analyzedSha":"a1af029e6e73cb17c36bff823d227747b28e91e1","analyzedAt":"2026-08-29T11:43:24.718Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}