Closed general

screenshot workspace: silent uploadFailed with no reason, and the fallback floods the caller with 465KB of base64 instead of writing screenshots/<file>.png

John Lauer · 1mo ago ·closed by John Lauer

hydrogen screenshot workspace: capture succeeds, save/upload silently fails, and the fallback floods the caller with half a megabyte of base64

Repro (adom container, Hydrogen live, sharing active):

$ adom-cli hydrogen screenshot status     -> sharing active, scopes: panel, workspace
$ adom-cli hydrogen screenshot workspace
{ "dataUrl": "data:image/png;base64,iVBORw0K...   <-- 465 KB of base64
  "method": "element-capture", "scope": "workspace", "uploadFailed": true }

Three problems, in order of pain:

  1. uploadFailed: true carries no reason. Local checks all pass — ~/project/screenshots/ exists and is writable, the control URL answers 200, the disk is at 2%. Whatever failed is invisible to the caller; an uploadError string would make this diagnosable.
  2. The fallback dumps the entire PNG as base64 to stdout. For an AI caller this is the worst possible shape: one screenshot consumed a ~466 KB tool result. The documented contract (hydrogen-self-screenshot) is "saves a PNG into the container's screenshots/ folder and prints the path" — on upload failure the CLI has the bytes IN HAND and could still write them to screenshots/ locally and print the path, which is strictly better than the base64 flood.
  3. Minor: the JSON's dataUrl field ordering puts half a megabyte before uploadFailed, so a streaming reader cannot even learn it failed without consuming the blob.

The capture pipeline itself is fine — I decoded the dataUrl and got a clean 2433x1452 workspace frame; it was even useful evidence for a dashboard fix. It is only the last hop that fails, and it fails without a word.

Filed from the altium-plan thread, 2026-09-01; happy to re-run with any diagnostic build.

2 Replies

John Lauer · 1mo ago

Triaged with John today: fix now, and the scope is his: screenshots always work. Not better error reporting around a failing upload; find why the save fails and make the PNG land under screenshots/ every time, with the path in the response and no base64 flood.

John Lauer · 1mo ago

Shipped in Hydrogen 1.0.387 (with adom-vscode 1.1.58 in the workspace).

Root cause: the proxy wrote every upload by spawning wsl.exe and piping the bytes to cat. A slow or wedged WSL management plane failed the save with no reason, and the frontend then returned the whole PNG as base64. The screenshot itself had always succeeded.

Fix, in the order you cared about: the write now goes to the adom-vscode extension's POST /fs/write, one HTTP call to a process already running inside the workspace, written as the adom user, no wsl.exe. wsl.exe is only the fallback when that route is not up at all. A save that still fails now says exactly why, and the data URL only comes back when the caller explicitly asks for the image inline, so no more half-megabyte base64 flood.

Verified on arav-rog: /fs/write lands the file under ~/project as adom and refuses a path outside the home directory.

Log in to reply.