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
getYouTubeClient requires an OAuth access token to initialize the YouTube Data API client. It first calls getUserAccessToken(accountId) to fetch the stored token for the given account; if no token is stored (or retrieval returns null), it throws 'No access token available, user needs to authorize'. This indicates the account has never completed the OAuth authorization flow or the stored token has been lost.
Source
Thrown at project/aitoearn-electron/server/src/modules/plat/youtube/youtube.auth.service.ts:562
// });
// console.log(`已创建新YouTube账号Token: ${accountTokenInfo.accountId} (${accountTokenInfo.userId})`);
// }
} catch (error) {
console.error('更新YouTube账号信息失败:', error);
// 不抛出异常,避免影响授权流程
}
}
/**
* 获取初始化后的YouTube API客户端
* @param accountId 账号id
* @returns 初始化后的YouTube API客户端
*/
async getYouTubeClient(accountId: string): Promise<any> {
const accessToken = await this.getUserAccessToken(accountId);
if (!accessToken) {
throw new Error('No access token available, user needs to authorize');
}
return this.initializeYouTubeClient(accessToken);
}
/**
* 检查用户是否已授权YouTube
* @param accountId 账号ID
* @returns 是否已授权
*/
async isAuthorized(accountId: string): Promise<boolean> {
try {
const accessToken = await this.getUserAccessToken(accountId);
return !!accessToken;
} catch (error) {
return false;
}
}View on GitHub (pinned to d3aa8bea5b)
Solutions
- Complete the OAuth authorization flow for this account by redirecting the user to the URL from GET /youtube/auth/url?mail=<email> and handling the callback so saveUserTokens persists the tokens
- Verify the accountId is correct and corresponds to an account that previously authorized; re-check the token store key google:accessToken:<userId>
- Check whether the user revoked access in their Google account (https://myaccount.google.com/permissions) and re-authorize
- If tokens are lost after redeploy, ensure the token storage (redis/db) volume persists
Example fix
// before
const client = await youtubeAuthService.getYouTubeClient(accountId);
// after
let client;
try {
client = await youtubeAuthService.getYouTubeClient(accountId);
} catch (e) {
if (e.message.includes('No access token')) {
const authUrl = await youtubeController.getAuthUrl(systemToken, email); // redirect user to authorize
throw new Error(`Authorization required. Visit: ${authUrl}`);
}
throw e;
} Defensive patterns
Strategy: try-catch
Validate before calling
const token = await tokenStore.get(`google:accessToken:${userId}`);
if (!token) throw new Error(`Account ${accountId} not authorized; redirect user to /youtube/auth/url?mail=${email}`); Type guard
function isAuthorizedAccount(acct: { accessToken?: string | null }): acct is { accessToken: string } {
return typeof acct.accessToken === 'string' && acct.accessToken.length > 0;
} Try / catch
try {
const client = await youtubeAuthService.getYouTubeClient(accountId);
} catch (e) {
if (e.message === 'No access token available, user needs to authorize') {
return res.redirect(authUrl); // start OAuth flow
}
throw e;
} Prevention
- Always complete the OAuth callback flow before using any YouTube API for an account
- Check token presence in storage before invoking account-dependent operations
- Monitor for revoked grants via 401 responses and trigger re-auth
- Use stable, correct accountIds; validate they exist before calling
When it happens
Trigger: Calling any YouTube operation that goes through getYouTubeClient with an accountId that has no stored access token: the account was never authorized, the authorization flow was abandoned, tokens were cleared from the store (google:accessToken:<userId> key missing/expired and deleted), or the wrong accountId is passed.
Common situations: Developer adds a YouTube account record in the database without completing the OAuth consent screen; token store flushed after restart without refresh token persistence; user revoked access in Google account settings so stored token was invalidated and removed; passing an internal account id that differs from the one bound to the OAuth grant.
Related errors
- ResponseCode.ChannelAccountNotAuthorized
- ChannelAuthRefreshTokenMissing
- ChannelAuthRefreshTokenMissing
- ChannelAuthRefreshTokenMissing
- 无效的账号或刷新令牌丢失
AI-assisted analysis of yikart/AiToEarn@d3aa8bea5b (2026-08-31).
Data as JSON: /api/errors/fa59489845c31d75.
Report an issue: GitHub.