Ti aiuterà a migliorare le tue conoscenze ma anche capire come iniziare questo viaggio!
I like OpenCode. It’s powerful but not moving so much fast. But if you’ve actually used it heavily, you’ve probably hit the same wall I did: sessions that hang, tools that don’t execute, agents that get stuck – and no clean way to recover.
This post is about the problems I kept hitting in OpenCode, why they’re harder than they look, and how I ended up building a plugin to fix them myself.
The Reality of Using OpenCode (Right Now)
On paper, everything works. In practice, things break in subtle, frustrating ways.
Here are the main failure modes I kept running into:
1. Streaming Just… Stops
You’re mid-response. The model is generating. Then nothing.
No error. No completion. Just silence.
The UI still thinks the session is “busy,” so you’re stuck watching a blinking cursor. You don’t know if it’s slow, dead, or waiting on something that will never happen.
This is one of the worst UX failures because it destroys trust. You stop believing the system will finish anything.
2. Tool Calls That Never Execute
Sometimes the model outputs a tool call—but instead of actually calling the tool, it prints it as text (often XML-style).
From the system’s perspective, nothing is wrong. The session is “idle.” No stall is detected.
But the action you needed never happened.
3. Hallucination Loops
This one is more subtle.
You hit “continue,” and the model keeps going—but it’s stuck in a loop. Same pattern, same mistakes, same structure.
You can hit continue again and again, and it will confidently dig itself deeper.
4. Stuck Parent Sessions After Subagents
If you’re using subagents, you’ve probably seen this:
- Subagent finishes correctly
- Parent session stays “busy” forever
No output. No resume. Just a dead parent waiting for something that already happened.
The Breaking Point
I didn’t want to wait weeks (or months) for these edge cases to be handled upstream.
So instead of complaining (opening another issue or a PR as they have thousands of them in queue), I built a plugin.
What the Plugin Actually Does
The goal wasn’t to add features. It was to make OpenCode reliable under failure.
1. Detects Silent Stalls
The plugin monitors SSE activity. If nothing happens for ~45 seconds (with a small grace period), it assumes the session is stuck.
Instead of freezing, it sends a "continue" automatically.
It retries with exponential backoff, and stops after a few attempts.
2. Recovers Broken Tool Calls
When a session goes idle, the plugin inspects recent messages.
If it detects tool calls written as raw text (instead of actual function calls), it triggers a resume.
This fixes a class of bugs that otherwise look like “nothing happened.”
3. Breaks Hallucination Cycles
The plugin tracks how often it has to “continue” a session.
If it sees too many resumes in a short window, it assumes the model is stuck in a loop.
At that point, it doesn’t keep pushing forward—it aborts and forces a clean restart.
4. Fixes Orphaned Parent Sessions
It watches how many sessions are active.
If multiple sessions drop down to one (typical subagent completion), it starts a timer.
If the parent doesn’t resume within that window, it gets forcefully restarted.
5. Avoids False Positives
This part matters more than the fixes themselves.
The plugin:
- Resets timers on any valid event
- Pauses stall detection when multiple sessions are active
- Differentiates between “idle” and “actually stuck”
