badges/shields · warning · NotFound
track not found
Error message
track not found
What it means
After filtering by architecture succeeds, `transform` filters the channel-map by the requested `track`. If no channel for that arch has that track (e.g. a non-default track like '3.x' or 'beta-track'), a NotFound with 'track not found' is thrown.
Source
Thrown at services/snapcraft/snapcraft-version.service.js:74
static defaultBadgeData = { label: 'snapcraft' }
static render({ version }) {
return renderVersionBadge({ version })
}
static transform(apiData, track, risk, arch) {
const channelMap = apiData['channel-map']
let filteredChannelMap = channelMap.filter(
({ channel }) => channel.architecture === arch,
)
if (filteredChannelMap.length === 0) {
throw new NotFound({ prettyMessage: 'arch not found' })
}
filteredChannelMap = filteredChannelMap.filter(
({ channel }) => channel.track === track,
)
if (filteredChannelMap.length === 0) {
throw new NotFound({ prettyMessage: 'track not found' })
}
filteredChannelMap = filteredChannelMap.filter(
({ channel }) => channel.risk === risk,
)
if (filteredChannelMap.length === 0) {
throw new NotFound({ prettyMessage: 'risk not found' })
}
return filteredChannelMap[0]
}
async handle({ package: packageName, track, risk }, { arch = 'amd64' }) {
const parsedData = await this.fetch(versionSchema, { packageName })
// filter results by track, risk and arch
const { version } = this.constructor.transform(
parsedData,
track,View on GitHub (pinned to 766fd8bc89)
Solutions
- Verify the snap's tracks via `snap info <name>` (lists tracks under 'channels') or the store page
- Omit the track param to use the default 'latest' track
- Correct the track name casing/spelling exactly as it appears in the store
- If the track should exist, push a release to it with `snapcraft release <revision> <track/risk>`
Example fix
// before /badge/snapcraft-version/my-snap?track=stable // after (stable is a risk, not a track) /badge/snapcraft-version/my-snap
Defensive patterns
Strategy: try-catch
Validate before calling
const snapInfo = await getSnapInfo(packageName); // snap info <name>
if (track && !snapInfo.tracks.includes(track)) throw new Error(`track ${track} not published`); Type guard
const trackExists = (track, tracks) => !track || (typeof track === 'string' && tracks.includes(track));
Try / catch
try {
return await getSnapcraftVersion({ package: name, track, risk, arch });
} catch (err) {
if (err prettyMessage === 'track not found') return getSnapcraftVersion({ package: name, risk, arch }); // omit track
throw err;
} Prevention
- Enumerate tracks via `snap info <name>` or the store API before requesting a track
- Remember 'stable'/'edge' are risks, not tracks; tracks are version-like names ('latest', '3.x')
- Default to latest track when unsure
When it happens
Trigger: Calling /snapcraft-version with `track=<name>` where the snap has no channels under that track for the given arch, e.g. track=4.0 for a snap that only publishes latest.
Common situations: Asking for an older/newer major-version track that the maintainer never created; assuming every snap has LTS tracks like Node's; typo in track name ('stable' is a risk, not a track).
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/95cc687344224181.
Report an issue: GitHub.