jackwener/OpenCLI · error · CommandExecutionError
${message}: malformed GeoGebra result
Error message
${message}: malformed GeoGebra result What it means
requireGgbSuccess() validates the object returned by the GeoGebra bridge (via ggbEval) before inspecting it. It throws CommandExecutionError when the result is not a plain object, meaning the browser bridge returned something unexpected (null, a string, undefined) rather than the expected { ok, ... } envelope.
Source
Thrown at clis/geogebra/utils.js:60
const raw = value == null || value === '' ? defaultValue : value;
const number = Number(raw);
if (!Number.isFinite(number) || (positive && number <= 0)) {
throw new ArgumentError(`${label} must be a ${positive ? 'positive ' : ''}finite number`);
}
return number;
}
export function normalizeCoords(value) {
const parts = String(value ?? '').split(',').map(s => s.trim());
if (parts.length !== 2) {
throw new ArgumentError('coords must be in "x,y" format (e.g. "1,2")');
}
return parts.map((part, idx) => normalizeNumber(part, idx === 0 ? 'x' : 'y'));
}
export function requireGgbSuccess(result, message) {
if (!isPlainObject(result)) {
throw new CommandExecutionError(`${message}: malformed GeoGebra result`);
}
if (!result.ok) {
throw new CommandExecutionError(result.error || message);
}
return result;
}
/**
* Navigate to GeoGebra Geometry (if not already there) and wait for
* the ggbApplet API to become available.
*/
export async function ensureApplet(page) {
let currentUrl = '';
try {
currentUrl = await page.getCurrentUrl();
} catch {
currentUrl = '';
}View on GitHub (pinned to 49907e53dc)
Solutions
- Check that the GeoGebra page is still loaded and the applet exists (re-run ensureApplet) before retrying the command.
- Verify unwrapBridgeEnvelope handles the bridge's actual envelope format; log the raw return value from page.evaluate to see what was received.
- Re-navigate to the GeoGebra Geometry page and retry the command once the applet reports ready.
- Catch CommandExecutionError around the tool call and treat it as a transient automation failure.
Example fix
// before
const result = await ggbEval(page, 'A=(1,2)');
requireGgbSuccess(result, 'Create point');
// after
let result = await ggbEval(page, 'A=(1,2)');
if (!isPlainObject(result)) { await ensureApplet(page); result = await ggbEval(page, 'A=(1,2)'); }
requireGgbSuccess(result, 'Create point'); Defensive patterns
Strategy: type-guard
Validate before calling
if (result == null || typeof result !== 'object' || Array.isArray(result)) { await ensureApplet(page); result = await ggbEval(page, cmd); } Type guard
const isPlainObject = (v) => typeof v === 'object' && v !== null && !Array.isArray(v);
Try / catch
try { requireGgbSuccess(result, 'Create point'); } catch (e) { if (String(e.message).includes('malformed')) { await ensureApplet(page); /* retry once */ } else throw e; } Prevention
- Re-run ensureApplet after any navigation or page replacement.
- Never share page handles across navigation boundaries without re-validating.
- Log raw evaluate output when debugging bridge format changes.
When it happens
Trigger: The page.evaluate call unwraps to a non-object (bridge/envelope mangled the return), the GeoGebra page was replaced mid-command, or a proxy/extension stripped the structured result so requireGgbSuccess receives null/undefined/string.
Common situations: Browser automation sessions where the applet iframe reloaded during a command, stale page handles after navigation, or a modified/misbehaving unwrapBridgeEnvelope layer returning raw values.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- GeoGebra command returned malformed result
- Unexpected Claude probe: ${JSON.stringify(result)}
- Failed to send message
- Failed to detect GeoGebra applet: ${err?.message || err}
- ggbApplet not available after waiting. Make sure the GeoGebr
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/fe889273b078d76d.
Report an issue: GitHub.