{"record":{"id":"895ce040a66b1ceb","repo":"yikart/AiToEarn","slug":"twitter-user-profile-not-found","errorCode":null,"errorMessage":"Twitter user profile not found","messagePattern":"Twitter user profile not found","errorType":"exception","errorClass":"TwitterPlatformException","httpStatus":null,"severity":"error","filePath":"project/aitoearn-backend/apps/aitoearn-server/src/core/channels/platforms/twitter/twitter.service.ts","lineNumber":194,"sourceCode":"    platformUid: string\n    displayName: string\n    avatarUrl?: string\n    username?: string\n    followersCount?: number\n    followingCount?: number\n    tweetCount?: number\n  }> {\n    const response = await this.runApiClientOperation({\n      accessToken,\n      endpoint: 'GET /2/users/me',\n      call: client => client.users.getMe({\n        userFields: ['id', 'name', 'profile_image_url', 'username', 'public_metrics'],\n      }),\n    })\n\n    const user = response.data\n    if (!user) {\n      throw new TwitterPlatformException('Twitter user profile not found')\n    }\n    const { followersCount, followingCount, tweetCount } = user.publicMetrics ?? {}\n    return {\n      platformUid: user.id,\n      displayName: user.name,\n      avatarUrl: user.profileImageUrl,\n      username: user.username,\n      followersCount,\n      followingCount,\n      tweetCount,\n    }\n  }\n\n  async createPost(\n    accessToken: string,\n    params: {\n      text: string\n      mediaIds?: string[]","sourceCodeStart":176,"sourceCodeEnd":212,"githubUrl":"https://github.com/yikart/AiToEarn/blob/d3aa8bea5b146a8675607cf0144d891aad3e9683/project/aitoearn-backend/apps/aitoearn-server/src/core/channels/platforms/twitter/twitter.service.ts#L176-L212","documentation":"getUserInfo fetches the authenticated Twitter user via GET /2/users/me with user fields. If the API response contains no user object, TwitterPlatformException('Twitter user profile not found') is thrown, indicating the platform did not return a profile for the given access token.","triggerScenarios":"Calling getUserInfo with an expired/revoked access token, a token whose scope lacks users.read, or a Twitter API response missing data due to platform errors or deleted/suspended account.","commonSituations":"Stale channel credentials after the user revoked the app, partially completed OAuth flow, token obtained for a different Twitter API project with restricted scopes.","solutions":["Re-authenticate the channel to obtain a fresh access token","Check the Twitter API response details/logs for an underlying error (401/403) instead of missing data","Confirm the token scope includes users.read / tweet.read","Verify the account is not suspended or deleted"],"exampleFix":"// before\nconst user = response.data\nif (!user) {\n  throw new TwitterPlatformException('Twitter user profile not found')\n}\n// after\nconst user = response.data\nif (!user) {\n  this.logger.warn(`Twitter /users/me returned no data, response.errors=${JSON.stringify(response.errors)}`)\n  throw new TwitterPlatformException('Twitter user profile not found')\n}","handlingStrategy":"try-catch","validationCode":"const canFetchProfile = (c: { accessToken?: string | null }) => typeof c.accessToken === 'string' && c.accessToken.length > 0","typeGuard":"function hasProfile(u: unknown): u is { id: string; name: string; profileImageUrl?: string } {\n  return !!u && typeof u === 'object' && 'id' in u\n}","tryCatchPattern":"try {\n  const info = await twitterService.getUserInfo(token)\n} catch (e) {\n  if (String(e?.message).includes('user profile not found')) {\n    await channelService.requestReauth(channelId)\n    return\n  }\n  throw e\n}","preventionTips":["Refresh access tokens before expiry","Re-auth channels on first profile-not-found error","Check token scopes at connection time","Log underlying Twitter API errors for diagnosis"],"tags":["twitter","oauth","user-profile","missing-data"],"backgroundTag":"platform-profile-not-found","analyzedSha":"d3aa8bea5b146a8675607cf0144d891aad3e9683","analyzedAt":"2026-08-31T14:19:24.185Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}