jackwener/OpenCLI · error · AuthRequiredError

message (describeTwitterApiError('TweetResultByRestId', rawR

Error message

message (describeTwitterApiError('TweetResultByRestId', rawResult.httpStatus))

What it means

When the TweetResultByRestId response carries an httpStatus, describeTwitterApiError maps it to a human-readable message which is thrown: 401/403 become AuthRequiredError('x.com', message); any other status becomes a CommandExecutionError with that message. This surfaces the actual Twitter API error (rate limit, blocked, auth rejected) with the right error class.

Source

Thrown at clis/twitter/article.js:251

          else if (blockType === 'code-block')       parts.push('\`\`\`\\n' + text + '\\n\`\`\`');
          else                                       parts.push(text);
        }

        return [{
          title,
          author: screenName,
          content: parts.join('\\n\\n') || legacy.full_text || '',
          url: 'https://x.com/' + screenName + '/status/' + tweetId,
        }];
      }
    `));
        if (!Array.isArray(rawResult) && !isPlainObject(rawResult)) {
            throw new CommandExecutionError('Twitter article response payload is malformed');
        }
        if (rawResult?.httpStatus) {
            const message = describeTwitterApiError('TweetResultByRestId', rawResult.httpStatus);
            if (rawResult.httpStatus === 401 || rawResult.httpStatus === 403) {
                throw new AuthRequiredError('x.com', message);
            }
            throw new CommandExecutionError(message);
        }
        if (rawResult?.error) {
            throw new CommandExecutionError(rawResult.error + (rawResult.hint ? ` (${rawResult.hint})` : ''));
        }
        if (!Array.isArray(rawResult)) {
            throw new CommandExecutionError('Twitter article response payload is malformed');
        }
        return rawResult;
    }
});

View on GitHub (pinned to 49907e53dc)

Solutions

  1. For 401/403: re-run twitter login to refresh the session cookies
  2. For 429: wait and retry later; reduce request volume
  3. Check the mapped message for the specific status meaning and follow its hint
  4. Verify the account can access the requested tweet (protected/deleted content yields auth/forbidden errors)

Example fix

// before
node cli.js twitter article <id>   // stale session -> 401
// after
node cli.js twitter login && node cli.js twitter article <id>
Defensive patterns

Strategy: try-catch

Type guard

function isAuthStatus(status) { return status === 401 || status === 403; }

Try / catch

import { AuthRequiredError } from '@jackwener/opencli/errors';
try {
  await articleCmd({ tweetId });
} catch (err) {
  if (err instanceof AuthRequiredError) {
    await runTwitterLogin();
    return articleCmd({ tweetId }); // one retry after re-auth
  }
  if (err.message.includes('429') || /rate limit/i.test(err.message)) {
    await sleep(60_000);
    return articleCmd({ tweetId });
  }
  throw err;
}

Prevention

When it happens

Trigger: The in-page fetch to the Twitter GraphQL endpoint returns a response with an httpStatus field — e.g. 401/403 for expired or insufficient auth, 429 rate limit, or other HTTP failures from api.x.com/graphql/TweetResultByRestId.

Common situations: Expired x.com session (401), account restrictions or private content (403), heavy scraping triggering 429 rate limits, or Twitter API changes altering endpoint behavior.

Related errors


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