jackwener/OpenCLI · error · CommandExecutionError
Failed to capture GeoGebra screenshot: ${err?.message || err
Error message
Failed to capture GeoGebra screenshot: ${err?.message || err} What it means
This CommandExecutionError wraps a failure of page.screenshot() inside the `geogebra triangle` command. The construction succeeded but Playwright could not write the PNG — the wrapper preserves the underlying Playwright message for diagnosis.
Source
Thrown at clis/geogebra/triangle.js:50
const r3 = requireGgbSuccess(await ggbEval(page, 'c=Circle(A,B)'), 'Failed to create circle c');
results.push({ step: 'c=Circle(A,B)', result: `ok (${r3.label || 'c'})` });
const r4 = requireGgbSuccess(await ggbEval(page, 'd=Circle(B,A)'), 'Failed to create circle d');
results.push({ step: 'd=Circle(B,A)', result: `ok (${r4.label || 'd'})` });
const r5 = requireGgbSuccess(await ggbEval(page, 'C=Intersect(c,d,1)'), 'Failed to create point C');
results.push({ step: 'C=Intersect(c,d,1)', result: `ok (${r5.label || 'C'})` });
const r6 = requireGgbSuccess(await ggbEval(page, 'Polygon(A,B,C)'), 'Failed to create triangle polygon');
results.push({ step: 'Polygon(A,B,C)', result: `ok (${r6.label || 'triangle created'})` });
const objectCount = await ggbWaitForObjectCount(page, 5);
const objects = await ggbListObjects(page);
const screenshotPath = path.join(os.tmpdir(), 'opencli-geogebra-triangle.png');
try {
await page.screenshot({ path: screenshotPath });
} catch (err) {
throw new CommandExecutionError(`Failed to capture GeoGebra screenshot: ${err?.message || err}`);
}
results.push({
step: `canvas has ${objectCount} objects`,
result: objects.map((obj) => `${obj.name}(${obj.type})`).join(', '),
});
results.push({ step: 'screenshot', result: screenshotPath });
return results;
},
});
View on GitHub (pinned to 49907e53dc)
Solutions
- Re-run the command; transient tab races usually clear
- Check the temp directory is writable (permissions, disk space) — screenshotPath uses os.tmpdir()/opencli-geogebra-triangle.png
- Keep the bound tab open and on www.geogebra.org for the whole command
- Read the appended Playwright message: 'Target closed' means re-bind the tab; filesystem errors mean fix the tmpdir
Example fix
// before # error: Failed to capture GeoGebra screenshot: EACCES: permission denied, open '/tmp/opencli-geogebra-triangle.png' // after export TMPDIR=$HOME/tmp && mkdir -p $HOME/tmp && opencli geogebra triangle --a 3 --b 4 --c 5
Defensive patterns
Strategy: retry
Validate before calling
// ensure temp dir writable before the command import fs from 'node:fs'; import os from 'node:os'; import path from 'node:path'; fs.accessSync(os.tmpdir(), fs.constants.W_OK);
Try / catch
try {
await run('geogebra', 'triangle', '--a', '3', '--b', '4', '--c', '5');
} catch (err) {
if (/Failed to capture GeoGebra screenshot/.test(err.message)) {
if (/Target closed|navigat/.test(err.message)) { await rebindTab(); return retry(); }
if (/EACCES|ENOSPC|ENOENT/.test(err.message)) { fixTmpdirPermissions(); return retry(); }
}
throw err;
} Prevention
- Don't close or navigate the bound tab while the command runs
- Verify TMPDIR/os.tmpdir() is writable, especially in containers and CI
- Monitor disk space; the screenshot needs free space in the temp directory
When it happens
Trigger: `geogebra triangle ...` completing its construction but failing at page.screenshot({path}) — e.g. the target tab was closed/navigated during the run, the page was destroyed, or Playwright cannot write to the temp path.
Common situations: Tab closed by user or timeout mid-command; headless browser shutdown; os.tmpdir() unwritable (permissions, full disk, read-only container); screenshot taken during navigation.
Related errors
- `Failed to capture GeoGebra screenshot: ${err?.message || er
- `Failed to inspect GeoGebra object: ${err?.message || err}`
- Verify command returned no metric for baseline
- File not found: ${path}
- File must be a readable text file: ${path}
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/b31ca1374b971e31.
Report an issue: GitHub.