jackwener/OpenCLI · error · CommandExecutionError
mubu: ${path}: HTTP ${result.status} ${result.error ?? ''}
Error message
mubu: ${path}: HTTP ${result.status} ${result.error ?? ''} What it means
When the in-page XHR fails (non-2xx status, network error, or an unparseable/empty response body), mubuPost throws CommandExecutionError with the API path, HTTP status, and error detail. This is the generic transport-level failure path, distinct from auth and API business-code errors.
Source
Thrown at clis/mubu/utils.js:45
xhr.open('POST', ${JSON.stringify(url)}, true);
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.setRequestHeader('Jwt-Token', token);
xhr.onload = () => {
let data = null;
try { data = JSON.parse(xhr.responseText); } catch {}
resolve({ ok: xhr.status >= 200 && xhr.status < 300, status: xhr.status, data });
};
xhr.onerror = () => resolve({ ok: false, status: 0, data: null, error: 'network error' });
xhr.send(${JSON.stringify(JSON.stringify(body))});
});
})()
`);
if (!result || result.error === 'no token') {
throw new AuthRequiredError(MUBU_DOMAIN, AUTH_HINT);
}
if (!result.ok || !result.data) {
throw new CommandExecutionError(`mubu: ${path}: HTTP ${result.status} ${result.error ?? ''}`);
}
const { data } = result;
if (data.code !== 0) {
if (isAuthFailure(data.code, data.message)) {
throw new AuthRequiredError(MUBU_DOMAIN, AUTH_HINT);
}
throw new CommandExecutionError(`mubu: ${path}: code=${data.code} ${data.message ?? ''}`);
}
return data.data;
}
export function formatDate(ts) {
if (!ts) return '';
const d = new Date(ts);
const pad = (n) => String(n).padStart(2, '0');
return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())} ${pad(d.getHours())}:${pad(d.getMinutes())}`;View on GitHub (pinned to 49907e53dc)
Solutions
- Check network connectivity / proxy settings for api2.mubu.com.
- Retry after a short delay if the status is 5xx or 429 (transient issues).
- Verify the API path is still valid — the error names the exact path that failed.
Example fix
// before
const data = await mubuPost(page, '/doc/list', body); // throws on 500
// after
try {
const data = await mubuPost(page, '/doc/list', body);
} catch (e) {
if (e instanceof CommandExecutionError && /HTTP 5\d\d/.test(e.message)) {
await new Promise(r => setTimeout(r, 2000));
return mubuPost(page, '/doc/list', body); // retry once
}
throw e;
} Defensive patterns
Strategy: retry
Validate before calling
// reachability probe before the call
await page.goto('https://api2.mubu.com', { waitUntil: 'domcontentloaded', timeout: 10000 }).catch(() => { throw new Error('api2.mubu.com unreachable'); }); Type guard
const isTransportError = (e) => e instanceof CommandExecutionError && /HTTP \d+|network error/.test(e.message);
Try / catch
try {
return await mubuPost(page, path, body);
} catch (e) {
if (isTransportError(e) && attempts < 3) {
await new Promise(r => setTimeout(r, 1000 * 2 ** attempts));
return retry(attempts + 1);
}
throw e;
} Prevention
- Add exponential backoff for 5xx/429 and network errors.
- Verify proxy/firewall rules allow api2.mubu.com.
- Log the failing path and status from the error message for diagnosis.
When it happens
Trigger: api2.mubu.com unreachable (offline, DNS, firewall), server returns 500/404, xhr.onerror fires ('network error'), or the response body is not valid JSON so data is null.
Common situations: Corporate proxies blocking the domain, mubu API outage or endpoint rename, browser extension interference, or rate limiting producing 429.
Understand the failure class
Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.
Related errors
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/85f8f46f90c16702.
Report an issue: GitHub.