jackwener/OpenCLI · error · AuthRequiredError

AuthRequiredError(MUBU_DOMAIN, AUTH_HINT)

Error message

AuthRequiredError(MUBU_DOMAIN, AUTH_HINT)

What it means

mubuPost runs an XHR inside the browser page and reads the Jwt-Token from localStorage. When the token is missing (result.error === 'no token'), it throws AuthRequiredError telling you to log in at mubu.com in that browser session.

Source

Thrown at clis/mubu/utils.js:42

      if (!token) return { ok: false, status: 0, data: null, error: 'no token' };
      return await new Promise((resolve) => {
        const xhr = new XMLHttpRequest();
        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 '';

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Open mubu.com in the controlled browser and log in, then retry.
  2. Point the CLI at the browser profile that already has the session (correct user-data-dir).
  3. Catch AuthRequiredError and surface the login hint to the user instead of retrying.

Example fix

// before
const data = await mubuPost(page, '/doc/list', body); // throws if not logged in
// after
try {
  const data = await mubuPost(page, '/doc/list', body);
} catch (e) {
  if (e instanceof AuthRequiredError) {
    await page.goto('https://mubu.com'); // prompt user to log in
    return;
  }
  throw e;
}
Defensive patterns

Strategy: try-catch

Validate before calling

const hasToken = await page.evaluate(() => !!localStorage.getItem('Jwt-Token'));
if (!hasToken) throw new Error('Not logged into mubu.com in this browser profile');

Type guard

const isLoggedIn = async (page) => page.evaluate(() => !!localStorage.getItem('Jwt-Token'));

Try / catch

try {
  const data = await mubuPost(page, path, body);
} catch (e) {
  if (e.name === 'AuthRequiredError') {
    await page.goto('https://mubu.com'); // let the user log in
  } else throw e;
}

Prevention

When it happens

Trigger: Calling any mubu API command in a browser profile where the user is not logged into mubu.com, after localStorage was cleared, or in a fresh automation profile with no cookies/localStorage.

Common situations: Headless browser contexts, incognito profiles, sessions purged from localStorage, or pointing the CLI at the wrong user-data-dir.

Related errors


AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29). Data as JSON: /api/errors/b517e521bda2a88c. Report an issue: GitHub.