Every agent invocation on a long issue thread fails immediately, on every model, with:
opencode attempt 1/3 for @junior (ollama-cloud/kimi-k2.7-code:cloud, timeout 1200s)
rc=126
--- events (0 lines) ---
--- stderr (trace) ---
/tmp/agents-scripts/run-agent.sh: line 202: /usr/bin/timeout: Argument list too long
All three attempts fail identically after failing over to a second provider, which rules out the model, the provider and the timeout. rc=126 with zero event lines means the process was never executed.
"$PROMPT" is passed as a single argv element. Linux caps an individual argument at MAX_ARG_STRLEN = 32 pages = 131,072 bytes, independent of the much larger total ARG_MAX. Exceed it and execve fails with E2BIG; bash attributes the error to the binary it was about to run, which is why it reads as a timeout problem rather than a prompt problem.
Measurement on the thread that broke
newest 100 comments (what the script keeps)
127,716 B — 124.7 KiB
MAX_ARG_STRLEN
131,072 B — 128.0 KiB
headroom before the prompt template, issue body and instructions are added
~3.3 KiB
The thread had been sitting just under the cliff for a while. Adding one ordinary 3.3 KiB comment tipped it over, and it would have failed on the next comment from anyone.
Why the current guard does not help
thread comments fetched: 100 (newest 100 kept) caps by count. The limit being hit is in bytes. One hundred short comments is fine; one hundred long ones is not — and this thread's largest single comments are 24 KB and 19 KB, so the count cap can pass while the byte total is triple the limit.
or pipe it on stdin if opencode run accepts -. Either removes the ceiling entirely.
Additionally, budget the thread in bytes rather than comments — e.g. keep newest comments until a 60 KiB budget is spent, then insert a truncation marker. That keeps the prompt bounded no matter how the thread grows, and leaves room for the template.
Impact
Any issue whose thread grows past ~120 KiB becomes permanently unworkable for every agent, and the failure gives no hint of the real cause. ffaerber/homelab#226 is in that state now.
## Symptom
Every agent invocation on a long issue thread fails immediately, on every model, with:
```
opencode attempt 1/3 for @junior (ollama-cloud/kimi-k2.7-code:cloud, timeout 1200s)
rc=126
--- events (0 lines) ---
--- stderr (trace) ---
/tmp/agents-scripts/run-agent.sh: line 202: /usr/bin/timeout: Argument list too long
```
All three attempts fail identically after failing over to a second provider, which rules out the model, the provider and the timeout. `rc=126` with zero event lines means the process was never executed.
Seen on `ffaerber/homelab` run 1919 (issue #226).
## Cause
`run-agent.sh:201`:
```bash
timeout -k 30 "$AGENT_TIMEOUT" \
opencode run --model "$MODEL" --auto --format json "$PROMPT" ${FILES:-}
```
`"$PROMPT"` is passed as a **single argv element**. Linux caps an individual argument at `MAX_ARG_STRLEN` = 32 pages = **131,072 bytes**, independent of the much larger total `ARG_MAX`. Exceed it and `execve` fails with `E2BIG`; bash attributes the error to the binary it was about to run, which is why it reads as a `timeout` problem rather than a prompt problem.
## Measurement on the thread that broke
| | |
|---|---|
| newest 100 comments (what the script keeps) | 127,716 B — **124.7 KiB** |
| `MAX_ARG_STRLEN` | 131,072 B — 128.0 KiB |
| headroom before the prompt template, issue body and instructions are added | ~3.3 KiB |
The thread had been sitting just under the cliff for a while. Adding one ordinary 3.3 KiB comment tipped it over, and it would have failed on the next comment from anyone.
## Why the current guard does not help
`thread comments fetched: 100 (newest 100 kept)` caps by **count**. The limit being hit is in **bytes**. One hundred short comments is fine; one hundred long ones is not — and this thread's largest single comments are 24 KB and 19 KB, so the count cap can pass while the byte total is triple the limit.
## Suggested fix
Stop putting the prompt on the command line:
```bash
printf '%s' "$PROMPT" > /tmp/agent_prompt.txt
timeout -k 30 "$AGENT_TIMEOUT" \
opencode run --model "$MODEL" --auto --format json --prompt-file /tmp/agent_prompt.txt ${FILES:-}
```
or pipe it on stdin if `opencode run` accepts `-`. Either removes the ceiling entirely.
Additionally, budget the thread in **bytes** rather than comments — e.g. keep newest comments until a 60 KiB budget is spent, then insert a truncation marker. That keeps the prompt bounded no matter how the thread grows, and leaves room for the template.
## Impact
Any issue whose thread grows past ~120 KiB becomes permanently unworkable for every agent, and the failure gives no hint of the real cause. `ffaerber/homelab#226` is in that state now.
Confirmed the failure point: .gitea/workflows/scripts/run-agent.sh:203 passes "$PROMPT" as a single argv element, and the issue thread can exceed Linux's per-argument ceiling MAX_ARG_STRLEN (~128 KiB).
opencode run --help shows no --prompt-file option; the positional message argument is an array, so the simple fix is to pass the prompt on stdin instead of the command line (or break it into multiple positional args, but stdin is cleaner).
opencode run with no positional message should read from stdin, as is conventional for CLI message tools. If it does not, the fallback is to split the prompt into several positional chunks — but that would still risk MAX_ARG_STRLEN on any single chunk > 128 KiB.
Recommended approach
Two related changes in run-agent.sh:
Immediate fix — avoid passing $PROMPT as an argv element:
This removes the per-argument ceiling entirely. Need to verify opencode run actually reads stdin when no message positionals are given; if it does not, we can pipe via a here-document or use a temp file plus multiple positional fragments.
Byte budget on the thread — add a helper before /tmp/thread.md is consumed that trims the kept comments to ~60 KiB (or some safe budget), inserting a … (older comments truncated) marker. This bounds the prompt even when the thread grows.
Effort estimate
Small: one shell script, ~10–20 lines changed.
Risk: low, but needs verification that opencode run accepts stdin without the positional message.
Who should build
This is a single-file shell change with a config/guard tweak — within the @junior lane. I can implement it once @pm gives the go-ahead. If opencode run stdin behavior turns out to be non-standard, I may need a quick check from @senior or @lead on the safest fallback.
No images or complex code involved, so this is text-only and safe for me.
details
🔧 9 tool calls · in 63585 · out 1333 tokens · subscription · model ollama-cloud/kimi-k2.7-code:cloud
## Assessment
Confirmed the failure point: `.gitea/workflows/scripts/run-agent.sh:203` passes `"$PROMPT"` as a single `argv` element, and the issue thread can exceed Linux's per-argument ceiling `MAX_ARG_STRLEN` (~128 KiB).
`opencode run --help` shows no `--prompt-file` option; the positional `message` argument is an array, so the simple fix is to **pass the prompt on stdin instead of the command line** (or break it into multiple positional args, but stdin is cleaner).
`opencode run` with no positional message should read from stdin, as is conventional for CLI message tools. If it does not, the fallback is to split the prompt into several positional chunks — but that would still risk `MAX_ARG_STRLEN` on any single chunk > 128 KiB.
## Recommended approach
Two related changes in `run-agent.sh`:
1. **Immediate fix** — avoid passing `$PROMPT` as an argv element:
```bash
printf '%s' "$PROMPT" | timeout -k 30 "$AGENT_TIMEOUT" \
opencode run --model "$MODEL" --auto --format json ${FILES:-} \
>/tmp/events.jsonl 2>/tmp/agent_err.log || rc=$?
```
This removes the per-argument ceiling entirely. Need to verify `opencode run` actually reads stdin when no message positionals are given; if it does not, we can pipe via a here-document or use a temp file plus multiple positional fragments.
2. **Byte budget on the thread** — add a helper before `/tmp/thread.md` is consumed that trims the kept comments to ~60 KiB (or some safe budget), inserting a `… (older comments truncated)` marker. This bounds the prompt even when the thread grows.
## Effort estimate
- Small: one shell script, ~10–20 lines changed.
- Risk: low, but needs verification that `opencode run` accepts stdin without the positional message.
## Who should build
This is a single-file shell change with a config/guard tweak — within the `@junior` lane. I can implement it once @pm gives the go-ahead. If `opencode run` stdin behavior turns out to be non-standard, I may need a quick check from @senior or @lead on the safest fallback.
No images or complex code involved, so this is text-only and safe for me.
<details>
<summary>details</summary>
🔧 9 tool calls · in 63585 · out 1333 tokens · subscription · model ollama-cloud/kimi-k2.7-code:cloud
🔧 **read**: `{"filePath":"/workspace/gitea/agents/run-agent.sh","limit":250}`
🔧 **grep**: `--prompt-file|prompt-file`
🔧 **glob**: ``
🔧 **read**: ``
🔧 **glob**: ``
🔧 **glob**: ``
🔧 **grep**: `opencode run`
🔧 **read**: `.gitea/workflows/scripts/run-agent.sh`
🔧 **bash**: `opencode run --help 2>&1 || true`
<sub>tokens — input 63585 (fresh 63585 · cache 0w / 0r) · output 1333 · reasoning 0 · **subscription**</sub>
</details>
<!-- 🤖 agent reply — do not trigger -->
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Symptom
Every agent invocation on a long issue thread fails immediately, on every model, with:
All three attempts fail identically after failing over to a second provider, which rules out the model, the provider and the timeout.
rc=126with zero event lines means the process was never executed.Seen on
ffaerber/homelabrun 1919 (issue #226).Cause
run-agent.sh:201:"$PROMPT"is passed as a single argv element. Linux caps an individual argument atMAX_ARG_STRLEN= 32 pages = 131,072 bytes, independent of the much larger totalARG_MAX. Exceed it andexecvefails withE2BIG; bash attributes the error to the binary it was about to run, which is why it reads as atimeoutproblem rather than a prompt problem.Measurement on the thread that broke
MAX_ARG_STRLENThe thread had been sitting just under the cliff for a while. Adding one ordinary 3.3 KiB comment tipped it over, and it would have failed on the next comment from anyone.
Why the current guard does not help
thread comments fetched: 100 (newest 100 kept)caps by count. The limit being hit is in bytes. One hundred short comments is fine; one hundred long ones is not — and this thread's largest single comments are 24 KB and 19 KB, so the count cap can pass while the byte total is triple the limit.Suggested fix
Stop putting the prompt on the command line:
or pipe it on stdin if
opencode runaccepts-. Either removes the ceiling entirely.Additionally, budget the thread in bytes rather than comments — e.g. keep newest comments until a 60 KiB budget is spent, then insert a truncation marker. That keeps the prompt bounded no matter how the thread grows, and leaves room for the template.
Impact
Any issue whose thread grows past ~120 KiB becomes permanently unworkable for every agent, and the failure gives no hint of the real cause.
ffaerber/homelab#226is in that state now.Assessment
Confirmed the failure point:
.gitea/workflows/scripts/run-agent.sh:203passes"$PROMPT"as a singleargvelement, and the issue thread can exceed Linux's per-argument ceilingMAX_ARG_STRLEN(~128 KiB).opencode run --helpshows no--prompt-fileoption; the positionalmessageargument is an array, so the simple fix is to pass the prompt on stdin instead of the command line (or break it into multiple positional args, but stdin is cleaner).opencode runwith no positional message should read from stdin, as is conventional for CLI message tools. If it does not, the fallback is to split the prompt into several positional chunks — but that would still riskMAX_ARG_STRLENon any single chunk > 128 KiB.Recommended approach
Two related changes in
run-agent.sh:Immediate fix — avoid passing
$PROMPTas an argv element:This removes the per-argument ceiling entirely. Need to verify
opencode runactually reads stdin when no message positionals are given; if it does not, we can pipe via a here-document or use a temp file plus multiple positional fragments.Byte budget on the thread — add a helper before
/tmp/thread.mdis consumed that trims the kept comments to ~60 KiB (or some safe budget), inserting a… (older comments truncated)marker. This bounds the prompt even when the thread grows.Effort estimate
opencode runaccepts stdin without the positional message.Who should build
This is a single-file shell change with a config/guard tweak — within the
@juniorlane. I can implement it once @pm gives the go-ahead. Ifopencode runstdin behavior turns out to be non-standard, I may need a quick check from @senior or @lead on the safest fallback.No images or complex code involved, so this is text-only and safe for me.
details
🔧 9 tool calls · in 63585 · out 1333 tokens · subscription · model ollama-cloud/kimi-k2.7-code:cloud
🔧 read:
{"filePath":"/workspace/gitea/agents/run-agent.sh","limit":250}🔧 grep:
--prompt-file|prompt-file🔧 glob:
🔧 **read**:🔧 glob:
🔧 **glob**:🔧 grep:
opencode run🔧 read:
.gitea/workflows/scripts/run-agent.sh🔧 bash:
opencode run --help 2>&1 || truetokens — input 63585 (fresh 63585 · cache 0w / 0r) · output 1333 · reasoning 0 · subscription