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
- Relax or remove the filter query param so existing releases match.
- Add `include_prereleases=1` if the repo only ships prereleases.
- 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
- Confirm the repo publishes formal GitHub Releases, not just tags.
- Set include_prereleases=1 for prerelease-only repos.
- Keep filter patterns in sync with your tagging scheme.
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.