Known issues
These are problems we have hit and can reproduce, each with the condition that triggers it and a workaround. Several of them fail without any error message. Most are in the session around the runtime, such as Chrome, the image or the Kasm viewer.
Browser
Section titled “Browser”Chrome ignores the debugging port without --user-data-dir
Section titled “Chrome ignores the debugging port without --user-data-dir”- Condition: Chrome 136 or later, started with
--remote-debugging-portbut no--user-data-dir. - Symptom: Chrome starts normally but opens no DevTools port, and prints nothing about it. Every
dom.*call returns a resolution error, “no CDP connection is attached”, a scenario that declares browser steps ends intest-error, and the/cdp/passthrough answers 502. - Workaround: add
--user-data-dir=<a directory>toAPP_ARGS.APP_ARGSreplaces the image’s default arguments, so repeat any you need, such as--start-maximized. See Compatibility.
file:// pages are blocked in Kasm’s browser images
Section titled “file:// pages are blocked in Kasm’s browser images”- Condition: navigating Chrome to a
file://URL in akasmwebbrowser image. The image’s managed policy (/etc/opt/chrome/policies/managed/urlblocklist.json) blocksfile://*. - Symptom: the tab lands on
chrome-error://chromewebdata/, and every selector afterwards fails to match. - Workaround: serve the files over HTTP on loopback inside the session and navigate to that address. Leave the policy in place if you are testing the image as shipped.
The runtime attaches to the first tab Chrome lists
Section titled “The runtime attaches to the first tab Chrome lists”- Condition: more than one page is open in Chrome when the runtime attaches, for example an extension popup left open by an earlier run. The runtime always takes the first page target Chrome reports.
- Symptom:
cdp_*steps anddom.*calls act on the wrong page.report.json’scdp.target_urlshows which tab was attached. - Workaround: close popups and extra tabs before the run starts; a scenario that opens a popup can end by pressing Escape. Check
cdp.target_urlwhen browser steps fail on a page that looks right.
A screenshot straight after a browser step can show the previous page
Section titled “A screenshot straight after a browser step can show the previous page”- Condition: a scenario takes a visual judgement (
observe:orexpect:) immediately after acdp_*step. A navigation returns when the page is committed, before it is painted. - Symptom: the judgement sees the page as it was before the step.
- Workaround: put a
waitstep between the browser action and the visual check. Scenarios made only of browser steps are not affected.
Session and viewer
Section titled “Session and viewer”The framebuffer is not the size you asked for
Section titled “The framebuffer is not the size you asked for”- Condition: any of: a nix image with
VNC_RESOLUTIONunset (the default is 1280x720); a stock image, which ignoresVNC_RESOLUTION; a session requested through Kasm’s API withoutx_resandy_res, which default to 800x600 and overwriteVNC_RESOLUTION; a viewer that resized the session mid-run. - Symptom: clicks by fraction, vision-grounded clicks and baseline comparisons are wrong for the size the scenario was written at, with no error.
- Workaround: pin the size and refuse viewer resizes as described in Session geometry.
report.jsonrecords the real size asscreen.
A person’s clicks land in the wrong place in a scaled viewer
Section titled “A person’s clicks land in the wrong place in a scaled viewer”- Condition: a person watches a fixed-size session in a browser window that is not exactly the framebuffer’s size, so the viewer shows the session stretched or shrunk.
- Symptom: the person’s clicks reach the session at the page pixel rather than the screen pixel they aimed at. A click aimed at (512, 461) on a 1024x768 session shown at 1400x1000 arrived at (700, 600). Observed on 2026-09-24 with the
chrome:niximage; clicks are exact at 1:1. The cause is not confirmed. The runtime’s own clicks go straight to the X server and are not affected. - Workaround: size the browser window so the viewer shows the session at exactly its framebuffer size. The
10-playwright-verifyexample in the SDK is a test that catches this at the viewer sizes you care about.
Judgments come back empty from a thinking model
Section titled “Judgments come back empty from a thinking model”- Condition: a model that reasons before answering, with a reply-length cap it can reach. The server then returns HTTP 200 with empty content instead of an error.
- Symptom: screenshot judgements and grounded clicks return nothing, and after repeated failures the runtime may stop calling the model.
- Workaround: keep
KASM_RUNTIME_MAX_TOKENS_JUDGEat its default of 2000 or raise it, and make sure no proxy in front of the model sets a lower cap. Where the server offers a non-thinking mode, use it for judging.
The runtime stops using the model for the rest of the run
Section titled “The runtime stops using the model for the rest of the run”- Condition: judgement calls fail in a row, every retry used up,
KASM_RUNTIME_MODEL_DISABLE_AFTERtimes (default 2). A model that is still thinking whenKASM_RUNTIME_MODEL_TIMEOUT_S(default 90) runs out counts as a failure. - Symptom: the run finishes in deterministic-only mode and the report notes that the vision endpoint was degraded. Screenshots are still taken but nothing is judged, and a
goal:scenario cannot continue. Over MCP,screen.judge,screen.groundandscreen.askreturn a resolution error for the rest of the session. - Workaround: fix the endpoint first. For a slow or shared server, raise
KASM_RUNTIME_MODEL_TIMEOUT_S,KASM_RUNTIME_MODEL_ATTEMPTSorKASM_RUNTIME_MODEL_DISABLE_AFTER. See Operator file.
Evidence
Section titled “Evidence”A person’s keystrokes are hidden while the runtime types
Section titled “A person’s keystrokes are hidden while the runtime types”- Condition:
KASM_RUNTIME_OBSERVE_INPUT=true, and a person types in the viewer during aninput.typeorinput.keycall, or while a scenario’s typing step runs. - Symptom: those key events are recorded with
private: trueand no key or text, soinput.wait_fordoes not match them. The input still reaches the session. The runtime hides them because what it types may be a credential. - Workaround: keep people and the runtime from typing at the same time. When a wait misses, look for
private: trueentries in itseventsto see why.
A fatal log line far back in a chatty log is missed
Section titled “A fatal log line far back in a chatty log is missed”- Condition: the line that shows the application failed is more than
evidence.log_tail_lineslines (default 200) from the end of its log, or outside the last 512 KiB of the file. - Symptom: the scenario’s
log_fatalpatterns do not fire, and the line does not appear in the report’s log excerpts. - Workaround: raise
KASM_RUNTIME_EVIDENCE_LOG_TAIL_LINES. The 512 KiB window is fixed.
Kasm setup
Section titled “Kasm setup”Registering the port map does nothing with too few permissions
Section titled “Registering the port map does nothing with too few permissions”- Condition: registering the runtime’s port map on an image (the SDK helper’s
ensure-port-map) with an API key that hasIMAGES_MODIFYbut notIMAGES_MODIFY_RESOURCES. Kasm restricts an image’srun_config, where the port map lives. - Symptom: the call succeeds but the port map is not saved, so the session’s MCP endpoint cannot be reached through Kasm.
- Workaround: use a key with
IMAGES_VIEW,IMAGES_MODIFYandIMAGES_MODIFY_RESOURCES. The SDK helper’sbootstrap-api-keycreates one with exactly those.
- Compatibility: the images, browsers and settings these issues depend on.
- Environment variables: the settings named in the workarounds.
- How an action reaches the app: why frame size matters to some clicks and not others.