badges/shields · error · NotFound

no matching releases found

Error message

no matching releases found

What it means

fetchLatestRelease() fetches a repository's releases and throws NotFound when the list is empty. If a `filter` query param was supplied the message is 'no matching releases found', distinguishing 'the repo has releases but none match your filter' from 'no releases found'. It is a 404-style result meaning your filter criteria excluded every release.

Source

Thrown at services/github/github-common-release.js:150

  if (!includePrereleases && sort === 'date' && !filter) {
    const releaseInfo = await fetchLatestGitHubRelease(serviceInstance, {
      user,
      repo,
    })
    return releaseInfo
  }

  const releases = applyFilter({
    releases: await fetchReleases(serviceInstance, { user, repo }),
    filter,
    displayName,
  })
  if (releases.length === 0) {
    const prettyMessage = filter
      ? 'no matching releases found'
      : 'no releases found'
    throw new NotFound({ prettyMessage })
  }
  const latestRelease = getLatestRelease({ releases, sort, includePrereleases })
  return latestRelease
}

export { fetchLatestRelease, queryParamSchema, openApiQueryParams }

// currently only used for tests
export const _getLatestRelease = getLatestRelease
export const _applyFilter = applyFilter

View on GitHub (pinned to 766fd8bc89)

Solutions

  1. Relax or remove the filter query param so existing releases match.
  2. Add `include_prereleases=1` if the repo only ships prereleases.
  3. Confirm the repo actually has GitHub Releases (not just tags) at the Releases page; create one if needed.

Example fix

// before
/service/github/release/user/repo.json?filter=v1
// after
/service/github/release/user/repo.json?include_prereleases=1
Defensive patterns

Strategy: try-catch

Validate before calling

// check any release matches before requesting
const rels = await fetch('https://api.github.com/repos/OWNER/REPO/releases').then(r => r.json());
if (!rels.some(r => !r.prerelease && (!filter || r.tag_name.includes(filter)))) throw new Error('no matching releases');

Type guard

function hasMatchingReleases(releases, filter) {
  return Array.isArray(releases) && releases.some(r => r != null && typeof r.tag_name === 'string' && (!filter || r.tag_name.includes(filter)));
}

Try / catch

try {
  const release = await getLatestRelease({ user, repo, filter });
} catch (e) {
  if (e.prettyMessage === 'no matching releases found') {
    // retry without filter or show 'no release' badge state
  } else throw e;
}

Prevention

When it happens

Trigger: Calling a release-based service (e.g. github/release, downloads, latest release) with query params like `include_prereleases=false` combined with a repo whose only releases are prereleases, or a filter/label that matches no release tags.

Common situations: Repo publishes only prereleases while the badge defaults to excluding them; filtering by a release name/tag pattern that no longer exists after renaming; repos that use tags-only (no formal releases).

Related errors


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