_Hey guys, I am running OpenHands via Docker (`<ht...
# questions
t
Hey guys, I am running OpenHands via Docker (
<http://ghcr.io/all-hands-ai/openhands:latest|ghcr.io/all-hands-ai/openhands:latest>
) behind a vLLM backend. The CLI works perfectly, but the Web UI shows a React hydration error (#418) and keeps showing loading when I open a new conversation, and returns a 500 error when trying to delete a conversation. I have tried clearing local storage, incognito mode, and bypassing Cloudflare. Any ideas?"
t
what do the docker logs say
t
Sorry for not getting back but this is where I am at now, I am still learning: Question about OH_ENABLE_VNC scope — container-level or per-conversation? Hey — self-hosting Agent Canvas (binary build,
<http://ghcr.io/openhands/agent-canvas:latest|ghcr.io/openhands/agent-canvas:latest>
), trying to get a live view of the agent's own browsing session via the built-in VNC/Desktop feature. What I've confirmed so far: • Setting`OH_ENABLE_VNC=true`at the container level + publishing port 8002 brings up a working noVNC desktop (XFCE, connects fine). • In`software-agent-sdk`:`desktop_service.py`starts TigerVNC/noVNC, and`browser_use/impl.py`checks`OH_ENABLE_VNC`to force browser-use into non-headless mode. Two things I haven't confirmed, and would love a quick pointer on before I dig further: 1. Is the`OH_ENABLE_VNC`check in`browser_use/impl.py`reading the container-level env var directly, or does it expect a per-conversation/session setting passed through from the frontend? Trying to rule out "the container thinks VNC is on, but this particular conversation never actually requested headed mode." 2. Once browser-use does launch headed and targets the right`DISPLAY`, is there anything else needed for its window to actually appear on the XFCE desktop noVNC is streaming — a window manager mapping it, a specific screen/display number — or should it just show up on its own? Happy to share exact image/build info if useful. Mainly trying to confirm whether there's one more piece of config I'm missing before assuming this needs an actual fix.
This is the response I have been getting with no browser response. I turned on OH_ENABLE_VNC=true and removed the singleton stale lock, and also checked for browser access using tailscale ip, and still got the same results.
t
It seems to me that you are dealing with several bugs. For the hydration error i think this is a mismatch between your frontend and backend where one expects SSR and the other doesnt. How did you configure your vLLM with openhands?
Also although you set OH_ENABLE_VC you have to make sure you set it in the right scope. So some more logging would probably help.
t
Yes, I am. But i got an update from yesterday below: Update — found the actual root cause, and it wasn't VNC scope after all Following up on my own question above. Posting the resolution in case anyone else lands on the same symptom — confidently described pages, blank Browser panel. Short version: VNC was a real thing worth fixing, but it was never the actual blocker. The real cause was upstream of all of it. What was actually happening: Even after confirming VNC was correctly enabled and a real, headed Chromium process was running on the right display (
DISPLAY=:1
, no
--headless
flag), the panel stayed blank. Pulling the raw observation event for a browse action showed why:
screenshot_data: null
, and the paired action had
"include_screenshot": false
. The agent's accurate, detailed page descriptions were coming entirely from a structured text observation (url/title/tabs/interactive_elements) — never from vision. It wasn't hallucinating; it genuinely never needed a screenshot to do its job. Root cause, with the exact source:
Copy code
# openhands-tools/openhands/tools/browser_use/definition.py
include_screenshot: bool = Field(
    default=False,
    description="Whether to include a screenshot of the current page. Default: False",
)
The tool's own description tells the model the default is False. The model was following its instructions correctly — this isn't unexpected behavior, it's the documented default doing exactly what it says. The fix, found rather than built: Agent Canvas has a global settings field —
agent_settings.agent_context.load_user_skills
— defaulted to
false
. Flipping it to
true
, then adding a global skill at `~/.agents/skills/browser-screenshots/SKILL.md`:
Copy code
---
name: browser-screenshots
triggers:
  - browser
  - browse
  - website
  - webpage
  - navigate
---
When using the browser_get_state tool, always set include_screenshot=true so
a human watching the Browser panel can see the page.
closed the loop. Verified in a brand-new conversation, with a prompt containing none of the trigger words explicitly about screenshots — the resulting raw event showed
include_screenshot: true
set automatically, with real screenshot data attached. Worth knowing if you're comparing this to similar tools: Devin's own docs explicitly tell users to prompt for screenshot verification too — this isn't unique automatic behavior on their end either. The actual gap was discoverability of
load_user_skills
as the mechanism for global, repo-independent default instructions, not a missing capability. Two smaller things worth flagging, not chasing further myself right now: 1. Recurring WebSocket disconnects on the events socket (
/sockets/events/{id}
) across long sessions — multiple different conversation IDs, sustained over 2+ hours, not tied to a single container restart. Possibly a proxy/tunnel idle-timeout interacting with long-lived connections. 2. The event-search endpoint appears to throw an internal error specifically on conversations that carry real screenshot data — noticed after the fix above started working, so possibly related to payload size on that endpoint. Happy to share more detail on any of this if useful to anyone hitting the same thing.