yikart/AiToEarn · error · Error
No access token available, user needs to authorize
Error message
No access token available, user needs to authorize
What it means
getTwitterClient() calls getUserAccessToken(accountId) and, if it receives a falsy token, throws a plain Error('No access token available, user needs to authorize'). In practice this is nearly unreachable because getUserAccessToken throws a BadRequestException first (errors 450/451) when it cannot obtain a token; this line only fires if the token chain returns an empty string without throwing. It signals that the end user must complete Twitter OAuth before a client can be built.
Source
Thrown at project/aitoearn-electron/server/src/modules/plat/twitter/twitter.auth.service.ts:569
{ $unset: { 'refreshToken': 1, 'expiresAt': 1 } }
);
return true;
} catch (error) {
console.error('撤销Twitter授权失败:', error);
return false;
}
}
/**
* 获取初始化后的Twitter API客户端
* @param accountId 账号ID
* @returns 初始化后的客户端
*/
async getTwitterClient(accountId: string): Promise<any> {
const accessToken = await this.getUserAccessToken(accountId);
if (!accessToken) {
throw new Error('No access token available, user needs to authorize');
}
// 返回一个简单的API客户端,可以根据需要扩展
return {
headers: {
Authorization: `Bearer ${accessToken}`
},
baseUrl: TWITTER_API_V2_BASE_URL,
async get(endpoint: string, params = {}) {
// 这里可以实现实际的API调用逻辑
// 或者使用第三方Twitter客户端库
}
};
}
}
View on GitHub (pinned to d3aa8bea5b)
Solutions
- Ensure the account completed OAuth: GET /plat/twitter/auth/url then the callback, so tokens exist in Redis/Mongo
- Check authorization first via GET /plat/twitter/auth/check?accountId=... and surface a 're-authorize' flow to the user instead of calling getTwitterClient
- Catch this Error (and the BadRequestException from getUserAccessToken) and return 401-style guidance telling the user to re-authorize
- Prefer throwing an UnauthorizedException instead of generic Error so HTTP semantics are correct
Example fix
// before
const accessToken = await this.getUserAccessToken(accountId);
if (!accessToken) {
throw new Error('No access token available, user needs to authorize');
}
// after
const accessToken = await this.getUserAccessToken(accountId);
if (!accessToken) {
throw new UnauthorizedException('Twitter account not authorized; complete OAuth first');
} Defensive patterns
Strategy: try-catch
Validate before calling
const authorized = await twitterAuthService.isAuthorized(accountId);
if (!authorized) {
const { url } = await twitterAuthService.getAuthorizationUrl(userId, mail);
// redirect the user to url to authorize
} Type guard
function hasAccessToken(v: unknown): v is { headers: { Authorization: string } } {
return !!v && typeof v === 'object'
&& 'headers' in v
&& typeof (v as any).headers?.Authorization === 'string'
&& (v as any).headers.Authorization.startsWith('Bearer ');
} Try / catch
try {
const client = await twitterAuthService.getTwitterClient(accountId);
} catch (e) {
if (e instanceof UnauthorizedException || e instanceof BadRequestException || e.message.includes('No access token')) {
return { needsAuthorization: true };
}
throw e;
} Prevention
- Check /plat/twitter/auth/check before building a client
- Build a UI state that prompts re-authorization instead of calling APIs for unauthorized accounts
- Never assume a stored accountId is still authorized after revocation or token expiry
- Replace the generic Error with UnauthorizedException for correct HTTP semantics
When it happens
Trigger: Programmatic calls to getTwitterClient with an accountId whose cached and refreshed tokens resolve to an empty string — practically only if getUserAccessToken's error paths are bypassed or refactored to return empty instead of throwing.
Common situations: Internal service code or scripts calling getTwitterClient directly for an unauthorized account; refactors that change getUserAccessToken to return null/'' instead of throwing; calling before the OAuth callback stored any token.
Related errors
- ResponseCode.ChannelAccountNotAuthorized
- ChannelAuthRefreshTokenMissing
- Twitter user profile not found
- 无效的账号或刷新令牌丢失
- 刷新令牌后未能获取访问令牌
AI-assisted analysis of yikart/AiToEarn@d3aa8bea5b (2026-08-31).
Data as JSON: /api/errors/1ee6b0fcd92265a4.
Report an issue: GitHub.