jackwener/OpenCLI · error · AuthRequiredError

Flomo API returned HTTP ${resp.status}; please refresh your

Error message

Flomo API returned HTTP ${resp.status}; please refresh your Flomo login session

What it means

fetchFlomoJson treats HTTP 401 or 403 from the Flomo API as an authentication failure and throws AuthRequiredError (a distinct class from CommandExecutionError) with the domain flomoapp.com and the status code in the message. The CLI authenticates with a Bearer token scraped from the signed-in browser session's localStorage (`me.access_token`); a 401/403 means that token is no longer accepted by the API.

Source

Thrown at clis/flomo/memos.js:159

    updated_at: String(memo.updated_at || ''),
  };
}

async function fetchFlomoJson(url, token) {
  let resp;
  try {
    resp = await fetch(url, {
      headers: {
        Authorization: 'Bearer ' + token,
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
        Accept: 'application/json',
      },
    });
  } catch (err) {
    throw new CommandExecutionError(`Failed to fetch Flomo memos: ${err instanceof Error ? err.message : String(err)}`);
  }
  if (resp.status === 401 || resp.status === 403) {
    throw new AuthRequiredError(FLOMO_API_DOMAIN, `Flomo API returned HTTP ${resp.status}; please refresh your Flomo login session`);
  }
  if (!resp.ok) {
    throw new CommandExecutionError(`Flomo API returned HTTP ${resp.status}`);
  }
  try {
    return await resp.json();
  } catch (err) {
    throw new CommandExecutionError(`Flomo API returned malformed JSON: ${err instanceof Error ? err.message : String(err)}`);
  }
}

async function readAccessToken(page) {
  const token = unwrapBrowserResult(await page.evaluate(buildGetTokenJs()));
  if (typeof token !== 'string' || !token.trim()) {
    throw new AuthRequiredError(FLOMO_API_DOMAIN, 'Flomo memos requires an active signed-in Flomo browser session');
  }
  return token.trim();
}

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Open https://v.flomoapp.com in the browser profile used by the CLI and log in / refresh the session.
  2. Confirm you are still signed in to Flomo in that browser (check the `me` localStorage entry for access_token).
  3. Clear Flomo cookies/localStorage for the profile and sign in again to issue a fresh token.
  4. Re-run the CLI immediately after re-login so the freshly scraped token is used.

Example fix

// before: running CLI against a stale browser profile
$ opencli flomo memos --limit 20
AuthRequiredError: Flomo API returned HTTP 401; please refresh your Flomo login session
// after: re-authenticate the browser profile first
$ opencli auth flomo   # opens browser, sign in, session refreshed
$ opencli flomo memos --limit 20  # 200 OK
Defensive patterns

Strategy: try-catch

Validate before calling

// verify a token exists in the browser session before calling the API
const token = await readAccessToken(page); // throws AuthRequiredError early if absent
// optionally probe the session cheaply first; a 401 here means re-login is needed

Type guard

null

Try / catch

import { AuthRequiredError } from '@jackwener/opencli/errors';
try {
  body = await fetchFlomoJson(url, token);
} catch (err) {
  if (err instanceof AuthRequiredError) {
    // token expired/revoked: trigger interactive re-login, then retry once
    await refreshFlomoSession();
    body = await fetchFlomoJson(url, await readAccessToken(page));
  } else { throw err; }
}

Prevention

When it happens

Trigger: Calling `flomo memos` when the browser's stored Flomo access_token has expired or been revoked; user logged out of Flomo in the automation browser; Flomo invalidated old sessions after a password change or security event; token copied from a different/stale profile.

Common situations: Long-lived headless browser profile whose Flomo session expired (Flomo tokens have limited lifetime); password reset invalidating all sessions; running the CLI on a machine where the browser was never signed in to Flomo; Flomo server-side session revocation.

Related errors


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