jackwener/OpenCLI · error · CommandExecutionError

Failed to add @${username} to list ${listId}: HTTP ${addResu

Error message

Failed to add @${username} to list ${listId}: HTTP ${addResult?.status ?? 0}${addResult?.fetchError ? ' (' + addResult.fetchError + ')' : ''}${addResult?.raw ? ' — ' + addResult.raw : ''}

What it means

A CommandExecutionError from buildListAddMemberRow in `clis/twitter/list-add-core.js` thrown when the HTTP layer of the X list-add mutation did not succeed (addResult.httpOk is false). The message embeds the HTTP status (0 when unknown) plus any fetchError or raw body text captured for diagnosis.

Source

Thrown at clis/twitter/list-add-core.js:56

    standardized_nudges_misinfo: true,
    tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled: true,
    longform_notetweets_rich_text_read_enabled: true,
    longform_notetweets_inline_media_enabled: true,
    responsive_web_grok_image_annotation_enabled: true,
    responsive_web_enhance_cards_enabled: false,
};

function fatalGraphqlErrors(errors) {
    const list = Array.isArray(errors) ? errors : [];
    return list.filter((e) =>
        !(e?.path || []).join('.').includes('default_banner_media_results')
        && !/decode/i.test(e?.message || '')
    );
}

export function buildListAddMemberRow({ addResult, memberCountBefore, listId, username, userId }) {
    if (!addResult?.httpOk) {
        throw new CommandExecutionError(
            `Failed to add @${username} to list ${listId}: HTTP ${addResult?.status ?? 0}${addResult?.fetchError ? ' (' + addResult.fetchError + ')' : ''}${addResult?.raw ? ' — ' + addResult.raw : ''}`
        );
    }

    // X often returns a partial GraphQL error on `default_banner_media_results`
    // even on successful mutations. Treat only missing main data or non-decode
    // GraphQL errors as command failures.
    const hasMemberCount = addResult.mc !== null && addResult.mc !== undefined;
    const fatalErrors = fatalGraphqlErrors(addResult.errors);
    if (!hasMemberCount && fatalErrors.length) {
        const msg = fatalErrors.map((e) => e.message || JSON.stringify(e)).join('; ');
        throw new CommandExecutionError(`Failed to add @${username} to list ${listId}: ${msg.slice(0, 300)}`);
    }
    if (!hasMemberCount) {
        throw new CommandExecutionError(`Failed to add @${username} to list ${listId}: no member_count in response`);
    }

    const memberCountAfter = Number(addResult.mc);

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Refresh your X login cookies and rerun — 401/403 usually means a stale session.
  2. Check the embedded HTTP status: 429 means back off and retry later; 403 means the account cannot edit this list.
  3. Verify the listId belongs to the authenticated account (only the list owner can add members).
  4. Check connectivity/proxy settings if status is 0 with a fetchError.

Example fix

// before: stale cookies produce HTTP 403
await listAddUser(page, { listId: '123456789', username: 'alice' });
// after: refresh session cookies first, then retry
await refreshSessionCookies(page);
await listAddUser(page, { listId: '123456789', username: 'alice' });
Defensive patterns

Strategy: try-catch

Validate before calling

// preflight: verify session and ownership before mutating
const cookies = await page.getCookies({ url: 'https://x.com' });
if (!cookies.some(c => c.name === 'auth_token')) throw new Error('No X auth cookies; refresh session first');

Type guard

function isHttpOkAddResult(r) {
  return Boolean(r && typeof r === 'object' && r.httpOk === true);
}

Try / catch

try {
  await listAddUser(page, { listId, username });
} catch (e) {
  const m = /HTTP (\d+)/.exec(e.message);
  const status = m && Number(m[1]);
  if (status === 429) await sleep(15 * 60_000); // rate limited: back off
  else if (status === 401 || status === 403) await refreshSessionCookies(page);
  else if (status === 0) await checkConnectivity();
  throw e;
}

Prevention

When it happens

Trigger: Calling listAddUser/row where the underlying GraphQL add-member request returns a non-2xx status (e.g. 401/403 auth failure, 429 rate limit) or the fetch itself fails (status 0 with a fetchError).

Common situations: Expired X session cookies; account flagged or lacking permission to edit the list; rate limiting after many mutations; network errors / DNS failures before a response arrives.

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/e9c1a31d590b2a6e. Report an issue: GitHub.