Hmbown/CodeWhale · error · ExecError
harmony backend exposes display 1 only
Error message
harmony backend exposes display 1 only
What it means
switch_display on the HarmonyOS backend fails because the backend only exposes display 1: displays are enumerated from a snapshot_display probe and hdc offers a single display surface, so any other requested display index is rejected.
Solutions
- Pass index: 1, the only display this backend exposes.
- Skip switch_display entirely — the single device display is already active.
- Gate display-switching logic on backend type or on list_displays() results.
Example fix
// before
await backend.switch_display({ index: 0 });
// after
const displays = await backend.list_displays();
if (displays.length > 1) await backend.switch_display({ index: displays[0].index }); // index 1 on harmonyos Defensive patterns
Strategy: validation
Validate before calling
if (index !== 1) throw new TypeError('harmony backend exposes display 1 only'); Type guard
const isHarmonyDisplay = (i) => i === 1;
Try / catch
try { await backend.switch_display({ index }); } catch (e) { if (String(e.message).includes('display 1 only')) { /* single-display device; stay on display 1 */ } else throw e; } Prevention
- Check list_displays() before switching.
- Skip display switching on single-display (harmonyos) backends.
- Avoid hardcoding 0-based display indexes in cross-platform scripts.
When it happens
Trigger: Calling switch_display({index: 0}) or any index other than 1 on the harmonyos backend.
Common situations: Code written for multi-display macOS backends using 0-based display indexes; enumerating displays generically and switching to the 'first' one (index 0); ported automation scripts assuming multiple monitors.
Understand the failure class
Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.
Related errors
- cursor position does not exist on touch devices
- zoom is not supported on the harmony backend yet —…
- aa start failed
- Antigravity cloud-code is stream-only; blocking…
- Antigravity cloud-code tools are not implemented yet; send…
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/6cc0226efef896d2.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/plugins/computer-use/src/backends/harmonyos.mjs:168
connected,
targets,
capabilities: { screenshot: connected, accessibility_tree: connected, clipboard: false, recording: "snapshot-series" },
note: "HarmonyOS drives the device over hdc. Clipboard read/write is not exposed by hdc and fails closed. Recording muxes snapshot_display frames with ffmpeg.",
};
},
list_displays: async () => {
if (!displayPixels) {
const dir = fs.mkdtempSync(path.join(os.tmpdir(), "cu-hm-"));
try {
const shot = path.join(dir, "probe.jpeg");
await snapshot(shot);
displayPixels = jpegSize(fs.readFileSync(shot)) ?? { w: null, h: null };
} finally { fs.rmSync(dir, { recursive: true, force: true }).catch(() => {}); }
}
return [{ index: 1, name: "device", pixels: displayPixels, points: displayPixels, scale: 1, main: true }];
},
async switch_display({ index }) {
if (index !== 1) throw new ExecError("harmony backend exposes display 1 only");
return { activeDisplay: 1 };
},
list_apps: async () => {
const out = await deviceOut(["bm", "dump", "-a"], { timeoutMs: 25_000 });
const bundles = out.split("\n").map((s) => s.trim()).filter((s) => /^[a-zA-Z][\w.]*$/.test(s));
return { apps: bundles.map((b) => ({ name: b, bundle_id: b, kind: "bundle" })) };
},
list_windows: async (args = {}) => {
rejectAppSelectors(args);
const out = await deviceOut(["hidumper", "-s", "WindowManagerService", "-a", "-a"], { timeoutMs: 25_000 }).catch(() => "");
const windows = out.split("\n").filter((l) => /Window Name|bundleName/i.test(l)).slice(0, 40).map((l) => ({ title: l.trim().slice(0, 160) }));
return { windows: windows.length ? windows : [{ title: "(window list unavailable on this HarmonyOS build)" }] };
},
open_application: async ({ bundle_id: bid, ability, name } = {}) => {
const bundle = bid ?? name;
const identifier = (value) => typeof value === "string" && value.length <= 256 && /^[A-Za-z_][A-Za-z0-9_]*(?:\.[A-Za-z_][A-Za-z0-9_]*)*$/.test(value);
if (!identifier(bundle)) throw new ExecError("open_application needs a valid Harmony bundle identifier");
if (ability != null && !identifier(ability)) throw new ExecError("open_application needs a valid Harmony ability identifier");View on GitHub (pinned to 73e0f67d83)