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

  1. Check network connectivity / proxy settings for api2.mubu.com.
  2. Retry after a short delay if the status is 5xx or 429 (transient issues).
  3. 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

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.