jackwener/OpenCLI · error · CommandExecutionError

Twitter profile response for @${screenName} is missing profi

Error message

Twitter profile response for @${screenName} is missing profile fields

What it means

CommandExecutionError thrown by mapTwitterProfileResult when the response is an object but contains neither result.legacy nor result.core — the two containers X uses for profile data. This means X responded but the payload lacks the expected profile structure.

Source

Thrown at clis/twitter/profile.js:48

    return typeof value === 'string' ? value : '';
}

function countField(...values) {
    for (const value of values) {
        if (typeof value === 'number' && Number.isFinite(value))
            return value;
    }
    return 0;
}

export function mapTwitterProfileResult(result, screenName) {
    if (!isPlainObject(result)) {
        throw new CommandExecutionError(`Twitter profile response for @${screenName} is malformed`);
    }
    const hasLegacy = isPlainObject(result.legacy);
    const hasCore = isPlainObject(result.core);
    if (!hasLegacy && !hasCore) {
        throw new CommandExecutionError(`Twitter profile response for @${screenName} is missing profile fields`);
    }
    const legacy = hasLegacy ? result.legacy : {};
    const core = hasCore ? result.core : {};
    if (!stringField(core.screen_name) && !stringField(legacy.screen_name) && !stringField(core.name) && !stringField(legacy.name) && !stringField(core.created_at) && !stringField(legacy.created_at)) {
        throw new CommandExecutionError(`Twitter profile response for @${screenName} is missing profile identity fields`);
    }
    const location = isPlainObject(result.location) ? result.location : {};
    const expandedUrl = stringField(result.website?.url) || stringField(legacy.entities?.url?.urls?.[0]?.expanded_url);
    return [{
        screen_name: stringField(core.screen_name) || stringField(legacy.screen_name) || screenName,
        name: stringField(core.name) || stringField(legacy.name),
        bio: stringField(result.profile_bio?.description) || stringField(legacy.description),
        location: stringField(location.location) || stringField(legacy.location),
        url: stringField(expandedUrl),
        followers: countField(result.relationship_counts?.followers, legacy.followers_count, legacy.normal_followers_count),
        following: countField(result.relationship_counts?.following, legacy.friends_count),
        tweets: countField(result.tweet_counts?.tweets, legacy.statuses_count),
        likes: countField(result.action_counts?.favorites_count, legacy.favourites_count),

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Confirm the account exists and is public by visiting the profile URL in the browser
  2. Try a different handle to determine if it's account-specific or a systemic API change
  3. Log in fresh — some payloads differ for degraded sessions
  4. If all handles fail, X changed its response shape; update mapTwitterProfileResult or the fetch call
Defensive patterns

Strategy: validation

Validate before calling

function looksLikeProfilePayload(res) {
  return res != null && typeof res === 'object' &&
    ('legacy' in res || 'core' in res);
}
// run on the raw response before mapping, when accessible

Type guard

const hasProfileContainers = (r) =>
  r != null && typeof r === 'object' && !Array.isArray(r) &&
  (isPlainObject(r.legacy) || isPlainObject(r.core));

Try / catch

try {
  const profile = await opencli('twitter profile', { username });
} catch (e) {
  if (e.name === 'CommandExecutionError' && /missing profile fields/.test(e.message)) {
    // account may be suspended/deleted or X changed the envelope
    console.warn('No profile data for', username, '- check account status');
  } else throw e;
}

Prevention

When it happens

Trigger: The GraphQL UserByScreenName response parses to an object missing both legacy and core fields — typically an error/tombstone object ('User is unavailable', suspended account) or a changed API envelope.

Common situations: Viewing a suspended, deleted, or protected account; X A/B testing a new response envelope; API version drift after X ships changes; the profile exists but lookup was served an error sub-object.

Related errors


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