jackwener/OpenCLI · error · CommandExecutionError

No avatar found — not logged in?

Error message

No avatar found — not logged in?

What it means

The account/whoami-style command scrapes the Kimi page for the user's avatar element to report AvatarAlt, AvatarUrl and nearby labels. If the in-page script returns null (no avatar element found), the command throws CommandExecutionError with the hint 'not logged in?'. It exists to distinguish an unauthenticated page from a successful but empty profile read.

Source

Thrown at clis/kimi/ui.js:164

        const data = await page.evaluate(`(() => {
      ${IS_VISIBLE_JS}
      const avatar = document.querySelector('img[src*="avatar.moonshot.cn"]');
      if (!avatar) return null;
      // The display name + plan are siblings in a parent container.
      let container = avatar;
      for (let i = 0; i < 5; i++) { if (container.parentElement) container = container.parentElement; }
      const spans = Array.from(container.querySelectorAll('span, div')).filter(isVisible)
        .map((el) => (el.innerText || el.textContent || '').trim())
        .filter((t) => t && t.length < 60);
      const uniq = [...new Set(spans)];
      return {
        avatarUrl: avatar.src,
        avatarAlt: avatar.alt || '',
        labels: uniq.slice(0, 10),
      };
    })()`);
        if (!data) {
            throw new CommandExecutionError('No avatar found — not logged in?', '');
        }
        const rows = [
            { Field: 'AvatarAlt', Value: data.avatarAlt || '(none)' },
            { Field: 'AvatarUrl', Value: data.avatarUrl },
        ];
        data.labels.forEach((l, i) => rows.push({ Field: `Label[${i + 1}]`, Value: l }));
        return rows;
    },
});

// -------- model --------
cli({
    site: 'kimi',
    name: 'model',
    access: 'write',
    description: 'Read the current Kimi model (e.g. "K2.6 思考") or switch by clicking the model dropdown. With no argument, returns current; with --list, opens dropdown + lists; with --set <name>, switches.',
    domain: KIMI_DOMAIN,
    strategy: Strategy.COOKIE,

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Log in to Kimi in the controlled browser and persist the session before running the command.
  2. Re-authenticate: open Kimi manually, complete login, then retry.
  3. Check you are on the intended Kimi page (not a login redirect).
  4. Update the library if Kimi changed its avatar markup.

Example fix

// before
const data = await page.evaluate(avatarScript); // throws if not logged in
// after
if (page.url().includes('login')) await performLogin(page);
const data = await page.evaluate(avatarScript);
Defensive patterns

Strategy: try-catch

Validate before calling

// detect login redirect before scraping profile data
if (page.url().includes('login')) throw new Error('Not logged in to Kimi');

Type guard

const hasAvatarData = (d) => !!d && typeof d.avatarUrl === 'string' && d.avatarUrl.length > 0;

Try / catch

try {
  const info = await getKimiAccount(page);
} catch (e) {
  if (/No avatar found/.test(e.message)) {
    await loginKimi(page); // re-establish session
    return getKimiAccount(page);
  }
  throw e;
}

Prevention

When it happens

Trigger: The injected evaluate script finds no avatar element — the user is not logged in, the session cookie expired, or the page layout no longer contains the expected avatar selector.

Common situations: Automation running without a persisted login session; Kimi logged the account out between runs; changed UI removed/moved the avatar node; navigating to the profile page while on a login redirect.

Related errors


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