badges/shields · error · NotFound

${this.constructor.type} not found

Error message

${this.constructor.type} not found

What it means

The YouTube base service throws NotFound with message '<type> not found' when the YouTube Data API reports pageInfo.totalResults === 0 for the given channelId or videoId, meaning no channel/video matched the id. The API call itself succeeded (key valid, quota OK).

Source

Thrown at services/youtube/youtube-base.js:90

        {
          schema,
          url: `https://www.googleapis.com/youtube/v3/${this.constructor.type}s`,
          options: {
            searchParams: { id, part: 'statistics' },
          },
          httpErrors: {
            400: `${this.constructor.type} not found`,
          },
        },
      ),
    )
  }

  async handle({ channelId, videoId }) {
    const id = channelId || videoId
    const json = await this.fetch({ id })
    if (json.pageInfo.totalResults === 0) {
      throw new NotFound({
        prettyMessage: `${this.constructor.type} not found`,
      })
    }
    const statistics = json.items[0].statistics
    return this.constructor.render({ statistics, id })
  }
}

class YouTubeVideoBase extends YouTubeBase {
  static type = 'video'
}

class YouTubeChannelBase extends YouTubeBase {
  static type = 'channel'
}

export { description, YouTubeVideoBase, YouTubeChannelBase }

View on GitHub (pinned to 766fd8bc89)

Solutions

  1. Verify the id: for channels use the UC... channelId from the channel page source (or via a handle-to-id lookup), not the @handle or vanity URL
  2. Open the video/channel URL to confirm it still exists and is public
  3. Check that the value is passed in the correct parameter (channelId vs videoId)
  4. If the resource was deleted or made private, remove or update the badge

Example fix

// before
handle({ channelId: '@MyChannel' })
// after
handle({ channelId: 'UC_x5XG1OV2P6uZZ5FSM9Ttw' })
Defensive patterns

Strategy: validation

Validate before calling

// resolve a YouTube handle to a channelId and verify existence before rendering
const lookup = await fetch(`https://www.googleapis.com/youtube/v3/channels?part=id&forHandle=${handle}&key=${KEY}`).then(r => r.json())
if (lookup.pageInfo.totalResults === 0) throw new Error('channel not found');

Type guard

function channelExists(json) { return json?.pageInfo?.totalResults > 0 && Array.isArray(json.items) && json.items.length > 0 }

Try / catch

try {
  const badge = await ytService.handle({ channelId, videoId })
} catch (e) {
  if (e.message.endsWith('not found')) {
    // render 'youtube | not found'
  } else throw e
}

Prevention

When it happens

Trigger: Calling a youtube badge (views, likes, comments) with a channelId or videoId that returns zero results — deleted resource, wrong id format, or an id for a different resource type.

Common situations: Channel deleted or terminated, using a custom handle (e.g. @name) instead of the numeric/channel id, video made private or removed, swapping channelId and videoId parameters, region-blocked resources.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


AI-assisted analysis of badges/shields@766fd8bc89 (2026-08-30). Data as JSON: /api/errors/f3e2a3256bc6783e. Report an issue: GitHub.