yikart/AiToEarn · error · Error

未检测到可用的 YouTube 频道,请先创建频道

Error message

未检测到可用的 YouTube 频道,请先创建频道

What it means

During uploadVideo, the service calls youtube.channels.list({ mine: true }) to verify the authenticated account owns a YouTube channel. If Google returns no items (empty data.items) the service throws this Error: the OAuth account exists but has no YouTube channel. A related path converts a youtubeSignupRequired API error into the sibling message 494.

Source

Thrown at project/aitoearn-electron/server/src/modules/plat/youtube/youtube.service.ts:685

 */
  async uploadVideo(userId, accountId, accessToken, file, title, description, keywords, categoryId, privacyStatus, publishAt) {
    // 获取当前最大的 id
    const maxRecord = await this.PubRecordModel.findOne().sort({ id: -1 });
    const newId = maxRecord ? maxRecord.id + 1 : 1;
    try {
      // 设置 OAuth2 客户端凭证
      this.oauth2Service.setCredentials(accessToken);
      const oauth2Client = this.oauth2Service.getClient();

      try {
        const channelInfo = await this.youtubeService.channels.list({
          part: ['snippet'],
          mine: true,
          auth: oauth2Client,
        });

        if (!channelInfo.data.items || channelInfo.data.items.length === 0) {
          throw new Error('未检测到可用的 YouTube 频道,请先创建频道');
        }

        // 可以上传
      } catch (err) {
        if (err.errors?.[0]?.reason === 'youtubeSignupRequired') {
          throw new Error('当前账号未启用 YouTube,请先创建频道');
        }
      }


      // 准备视频的元数据
      const fileStream = Readable.from(file.buffer); // 使用文件的 Buffer 转为可读取流
      const fileSize = file.size;  // 获取文件大小

      // 构造请求体
      let requestBody: any = {
        snippet: {
          title: title,

View on GitHub (pinned to d3aa8bea5b)

Solutions

  1. Sign in to youtube.com with the account and complete channel creation (choose handle/name).
  2. Re-authenticate after channel creation and retry the upload with a fresh access token.
  3. Verify with the API: channels.list(part=snippet, mine=true) returns at least one item before uploading.
  4. For Workspace accounts, ask the admin to enable YouTube service, or use a personal Google account.

Example fix

// before
await youtubeService.uploadVideo(accountIdWithoutChannel, file);
// after
const channels = await youtube.channels.list({ part: ['snippet'], mine: true, auth: oauth2Client });
if (!channels.data.items?.length) throw new Error('Create a YouTube channel for this account first');
await youtubeService.uploadVideo(accountId, file);
Defensive patterns

Strategy: try-catch

Validate before calling

const ch = await fetch('https://www.googleapis.com/youtube/v3/channels?part=snippet&mine=true', { headers: { Authorization: `Bearer ${token}` } });
const chData = await ch.json();
if (!chData.items?.length) throw new Error('Account has no YouTube channel — create one at youtube.com before uploading');

Type guard

function hasChannel(res: { data?: { items?: unknown[] } }): boolean {
  return Array.isArray(res.data?.items) && res.data.items.length > 0;
}

Try / catch

try {
  await youtubeService.uploadVideo(accountId, file);
} catch (e) {
  if (String(e.message).includes('未检测到可用的 YouTube 频道')) {
    // surface UI prompt: open youtube.com to create a channel
  } else throw e;
}

Prevention

When it happens

Trigger: Uploading a video with an OAuth token whose Google account has never created a YouTube channel; the channels.list(mine=true) response returns items: [] or undefined; err.errors[0].reason === 'youtubeSignupRequired' from the channels call.

Common situations: Brand-new Google accounts used for automation; Google Workspace accounts where YouTube is disabled by admin policy; tokens issued from a Google login that never visited youtube.com and accepted channel creation.

Related errors


AI-assisted analysis of yikart/AiToEarn@d3aa8bea5b (2026-08-31). Data as JSON: /api/errors/e29a73fcf262f5b0. Report an issue: GitHub.