jackwener/OpenCLI · error

HTTP ${response.status} - make sure you are logged in to Ins

Error message

HTTP ${response.status} - make sure you are logged in to Instagram

What it means

Thrown by throwInstagramHttpError when the Instagram web_profile_info (or feed-by-username) endpoint returns HTTP 401 or 403, meaning Instagram rejected the request as unauthenticated or forbidden. The library throws it because these statuses almost always mean the browser session is not logged in or the session cookie is no longer accepted by Instagram's API. It distinguishes this case from a plain HTTP failure (error 1931) so the user knows to authenticate first.

Source

Thrown at clis/instagram/_shared/user-id.js:26

 */
export function buildResolveInstagramUserIdJs() {
    return `
  function normalizeInstagramUserId(value, label) {
    const id = typeof value === 'number' ? String(value) : (typeof value === 'string' ? value.trim() : '');
    if (!/^\\d+$/.test(id)) throw new Error(label);
    return id;
  }
  async function readInstagramJson(response, label) {
    try {
      return await response.json();
    } catch {
      throw new Error(label + ' returned invalid JSON');
    }
  }
  function throwInstagramHttpError(response, label, username) {
    if (response.status === 404) throw new Error('User not found: ' + username);
    if (response.status === 401 || response.status === 403) {
      throw new Error('HTTP ' + response.status + ' - make sure you are logged in to Instagram');
    }
    throw new Error(label + ' failed: HTTP ' + response.status);
  }
  const r1 = await fetch('https://www.instagram.com/api/v1/users/web_profile_info/?username=' + encodeURIComponent(username), opts);
  if (r1.status === 404) throw new Error('User not found: ' + username);
  if (!r1.ok && r1.status !== 400) throwInstagramHttpError(r1, 'Instagram web_profile_info', username);
  let userId = r1.ok ? normalizeInstagramUserId((await readInstagramJson(r1, 'Instagram web_profile_info'))?.data?.user?.id, 'Instagram web_profile_info returned no valid user id for: ' + username) : '';
  if (!userId) {
    const r1b = await fetch('https://www.instagram.com/api/v1/feed/user/' + encodeURIComponent(username) + '/username/?count=1', opts);
    if (!r1b.ok) throwInstagramHttpError(r1b, 'Instagram feed-by-username', username);
    userId = normalizeInstagramUserId((await readInstagramJson(r1b, 'Instagram feed-by-username'))?.user?.pk, 'Instagram feed returned no valid profile owner for: ' + username);
  }`;
}

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Run the Instagram auth/login flow (clis/instagram auth login) and complete it in the browser so a valid sessionid cookie is stored
  2. Verify cookies: check that a non-empty sessionid cookie exists for https://www.instagram.com (this is what hasInstagramSessionCookie checks)
  3. Re-login if the session expired — change of password or Instagram revoking sessions invalidates the old cookie
  4. If 403 persists after login, wait and retry later (Instagram may be rate-limiting/blocking the account) or use a different account
  5. Retry the command after re-authenticating

Example fix

// before: running profile lookup without a session
$ opencli instagram collection-list someuser
Error: HTTP 401 - make sure you are logged in to Instagram

// after: authenticate first
$ opencli instagram auth login
$ opencli instagram collection-list someuser
Defensive patterns

Strategy: try-catch

Validate before calling

// before calling the command, check the session cookie via the auth quick-check
const cookies = await page.getCookies({ url: 'https://www.instagram.com' });
if (!cookies.some(c => c.name === 'sessionid' && c.value)) {
  throw new Error('Not logged in to Instagram — run the login command first');
}

Type guard

function hasInstagramSession(cookies) {
  return Array.isArray(cookies) && cookies.some(
    c => c && c.name === 'sessionid' && typeof c.value === 'string' && c.value.length > 0
  );
}

Try / catch

try {
  await resolveInstagramUserId(username);
} catch (e) {
  if (/HTTP 40[13] - make sure you are logged in/.test(e.message)) {
    await instagramLogin();          // re-authenticate
    return resolveInstagramUserId(username);
  }
  throw e;
}

Prevention

When it happens

Trigger: fetch to https://www.instagram.com/api/v1/users/web_profile_info/?username=... (via throwInstagramHttpError on r1 or fallback r1b) returns 401/403 while resolving a username to a user id inside the page context, typically because the sessionid cookie is missing, expired, or flagged.

Common situations: Running an instagram CLI subcommand before running the site's `login` command; the saved Instagram session expired or was revoked (password change, 'logout of all sessions', Instagram server-side invalidation); Instagram rate-limiting or temporarily blocking the account's API access (403); using a headless profile whose cookies were cleared.

Related errors


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