No More "Stops Halfway": Hermes max_turns Is Now Unlimited by Default


You know the feeling: you ask Hermes to do a genuinely big job — refactor the whole repo, batch-process thousands of files, build a data pipeline end to end — and it’s working away, then suddenly it stops. Not an error. Not a question. Just… done. Half the task is finished, the rest is sitting there.

That wasn’t magic, it was a hard default limit Hermes used to have: within a single turn, the agent could call tools at most 500 times. Five hundred sounds like a lot, but any real task — search, read code, edit files, run tests, fix bugs, run tests again — burns through it fast. Worse, it stopped silently. You only noticed the half-finished work when you scrolled back through the conversation.

That default is gone: as of the main branch (post-v0.20.4), agent.max_turns is unlimited by default. This post explains what changed, why, and how to set a cap when you actually want one.

First: what max_turns actually is

max_turns (also called max iterations) limits how many times the agent can call tools within one turn — not how many turns you can have. Think of it this way: you send one message, Hermes starts working, and every file it reads, every command it runs, every API call it makes counts as one iteration. max_turns: 500 meant: in this turn it can do at most 500 units of work, then it must stop and hand control back to you.

In the old versions the default was 500. Plenty for everyday Q&A, but for tasks that need “read the codebase → change dozens of files → run tests → fix → run again”, 500 was an invisible ceiling. The task hit the cap midway and the remaining steps had to wait for a manual “continue”.

It got worse: if you wrote max_turns: none in your config to express “no limit”, the old code crashed with a TypeError (issue #82813) — or silently ignored the value. Sometimes it didn’t just fail gracefully; it could take down cron jobs and the gateway.

The new default: unlimited, unless you opt into a cap

This change (PR #90708) flips the default behavior entirely:

Setting Before Now
Not set (default) capped at 500 unlimited
max_turns: none TypeError crash unlimited
max_turns: null / unlimited / inf / infinity / 0 / -1 crash or ignored unlimited
max_turns: 200 capped at 200 capped at 200 (unchanged)

In other words: by default a task now runs to completion — no more silent cutoff. Every “unlimited” spelling (none, null, unlimited, infinite, infinity, inf, , 0, -1, case-insensitive and whitespace-tolerant) is now a first-class citizen, normalized by a single resolve_turn_limit() function. Write whichever you like — same result, and no crashes.

If you genuinely want a cap for some tasks, a positive integer still works exactly as before.

How to set a limit when you want one

Unlimited is the default, but it isn’t right for every scenario — say a cron job that runs hourly and you want it to do a bounded amount of work so it can’t accidentally spend a fortune. There are three ways to set a cap (lowest to highest precedence):

1. Config file (config.yaml)

agent:
  max_turns: 200   # at most 200 tool calls per turn

2. CLI

hermes config set agent.max_turns 200

3. Environment variable

export HERMES_MAX_ITERATIONS=200
hermes chat

All three flow through the same resolve_turn_limit() parser, so behavior is consistent no matter where you set it.

Don’t confuse it: goals.max_turns stays at 20

One thing that didn’t change: goals.max_turns keeps its default of 20.

agent.max_turns governs ordinary conversation turns; goals.max_turns governs goal mode (you give Hermes a long-term objective and let it keep working autonomously until done) — specifically how many auto-continue cycles it may run. Goal mode has its own budget protection: it pauses after 20 continuations and asks you to /goal resume or clear, so a fuzzy objective can’t burn money forever. The PR deliberately left that field alone — the two settings each do their own job.

So: want long tasks to stop being cut off? Use the unlimited default (nothing to configure). Want a brake on autonomous goal-chasing? Tune goals.max_turns.

Worth knowing now that it’s unlimited

With unlimited turns, two things are worth keeping in mind:

  • Cost awareness: the task runs to completion, which means it keeps calling the model API. If you care about spend, don’t rely on max_turns as a brake — use more precise tools like agent.run_budget_seconds (a wall-clock budget that gives you a heads-up at 80% elapsed) or the gateway’s idle timeout (fires only when the agent has been completely idle for a while). Those are “graceful brakes” — far nicer than stopping mid-task.
  • cron and gateway benefit too: because the cron scheduler and gateway config reads now share the same resolver, the old crash when writing none in cron config is fixed as well. Long cron tasks now run to completion in one pass.

Summary

agent.max_turns going from “default 500” to “default unlimited” is a pragmatic fix for the long-task experience: let tasks that should finish, finish; let people who want limits, set limits. The change is currently on the main branch (merged after v0.20.4) — once the next official release ships, a simple hermes update gets you there.

Want to go deeper on how Hermes handles turns and context? Check out our deep dive on error handling and recovery, or the long-task config guide with practical settings that keep tasks from getting stuck.