jackwener/OpenCLI · error · CommandExecutionError
${label}: unexpected evaluate result shape
Error message
${label}: unexpected evaluate result shape What it means
CommandExecutionError thrown by requireArrayResult when the value unwrapped from page.evaluate() is not an array. The Qoder CLI expects injected browser scripts to resolve to arrays (items, turns) and fails loudly instead of iterating a non-array. The label names which result was malformed.
Source
Thrown at clis/qoder/_utils.js:40
if (cs.visibility === 'hidden' || cs.display === 'none' || cs.opacity === '0') return false;
return true;
};
`;
export function unwrapEvaluateResult(payload) {
if (payload && typeof payload === 'object' && !Array.isArray(payload) && 'session' in payload && 'data' in payload) {
return payload.data;
}
return payload;
}
export async function evaluateQoder(page, script) {
return unwrapEvaluateResult(await page.evaluate(script));
}
export function requireArrayResult(value, label) {
if (!Array.isArray(value)) {
throw new CommandExecutionError(`${label}: unexpected evaluate result shape`);
}
return value;
}
export function parsePositiveInt(raw, fallback, label) {
const value = raw == null || raw === '' ? fallback : Number(raw);
if (!Number.isInteger(value) || value < 1) {
throw new ArgumentError(`${label} must be a positive integer`);
}
return value;
}
// Build a JS snippet that clicks the first visible element matching any
// of the given CSS selectors. Uses the full pointer-event chain to
// satisfy radix/headless menu libraries.
export function clickFirstScript(selectors) {
return `(() => {
${IS_VISIBLE_JS}View on GitHub (pinned to 49907e53dc)
Solutions
- Log the raw evaluate result to inspect the actual shape
- Update the injected script to return an array (e.g. Array.from(nodeList))
- Check whether the target page structure changed and revise selectors
- Verify unwrapEvaluateResult handles your automation driver's result wrapper
Example fix
// before (in evaluate script)
return document.querySelectorAll('.item'); // NodeList, not array
// after
return Array.from(document.querySelectorAll('.item')); Defensive patterns
Strategy: type-guard
Validate before calling
const result = await page.evaluate(script);
if (!Array.isArray(result)) console.error('evaluate returned:', result); Type guard
function isArrayOf(v, pred = () => true) { return Array.isArray(v) && v.every(pred); } Try / catch
let items;
try {
items = requireArrayResult(await page.evaluate(script), 'items');
} catch (e) {
if (/unexpected evaluate result shape/.test(e.message)) {
// dump raw value, revise the injected script, or retry after navigation
} else throw e;
} Prevention
- Always return arrays from evaluate scripts (Array.from on NodeLists)
- Re-check injected selectors whenever the target page updates
- Log raw evaluate results during development to catch shape drift early
When it happens
Trigger: Calling a qoder command whose evaluate script returns undefined, null, an object, or a serialized wrapper instead of an array — e.g. the page's data source changed, the script was updated to return an object, or evaluate serialization dropped the value.
Common situations: Target web app updated its DOM/API so the injected script returns a different shape; the evaluated script hits an error path returning undefined; page context changed after navigation; browser automation layer returning wrapped results the unwrap step doesn't recognize.
Related errors
- Unexpected 12306 probe: ${JSON.stringify(probe)}
- Waiting for 12306 tk auth cookie
- amazon.com
- Unexpected Amazon probe: ${JSON.stringify(probe)}
- amazon ${action} navigation lost the current browser target
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/fc26e93f130bc545.
Report an issue: GitHub.