Skip to content

[Bug] Headless --max-turns exits 0 instead of 2 when turn limit is reached #41

@Prodesire

Description

@Prodesire

Bug Description

The headless runner documents exit code 2 for reaching --max-turns, but the command exits 0 when the limit is reached before the agent reaches a final text answer.

Steps to Reproduce

  1. Run a local fake OpenAI-compatible HTTP server that always returns a list_files tool call with finish_reason: "tool_calls".
  2. Run:
export IAC_CODE_CONFIG_DIR="$(mktemp -d)"
export IAC_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1
export IAC_CODE_PROVIDER=OpenAPICompatible
export IAC_CODE_MODEL=fake-model
export IAC_CODE_API_KEY=test-key
export IAC_CODE_BASE_URL="http://127.0.0.1:<fake-server-port>/v1"
uv run iac-code --prompt loop --output-format json --max-turns 1

A related edge case:

uv run iac-code --prompt loop --output-format json --max-turns 0

Expected Behavior

When the turn limit is reached, the command should return exit code 2, consistent with the documented headless exit codes:

2 — reached max-turns limit

Actual Behavior

For --max-turns 1, the command exits with code 0 and returns only the tool result, with no final assistant text:

{
  "text": "",
  "tool_uses": [
    {
      "name": "list_files",
      "is_error": false
    }
  ]
}

For --max-turns 0, the command exits with code 0 and makes no LLM request.

Operating System

macOS

Python Version

Python 3.14.2

iac-code Version

0.3.0 (uv run iac-code --version output: iac-code v0.3.0)

LLM Provider

Other

IaC Type

Not applicable

Additional Context

Tested from a local source checkout with uv run iac-code on 2026-05-29. A local fake OpenAI-compatible HTTP server was used; no real LLM or cloud credentials were used.

Likely related code:

  • src/iac_code/cli/headless.py: documents EXIT_MAX_TURNS = 2 and only sets hit_max_turns when a MessageEndEvent has stop_reason == "max_turns".
  • src/iac_code/agent/agent_loop.py: the main loop iterates over range(self._max_turns) but appears to exhaust the loop without emitting a max-turns event.

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No fields configured for Bug.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions