badges/shields · warning · NotFound

risk not found

Error message

risk not found

What it means

Third filter in `transform`: after arch and track match, the channel-map is filtered by `risk` (stable/candidate/beta/edge). If nothing matches, NotFound 'risk not found' is thrown. Note that channels that exist for the track but only on other branches are already removed by earlier filters.

Source

Thrown at services/snapcraft/snapcraft-version.service.js:80

  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,
      risk,
      arch,
    )
    return this.constructor.render({ version })
  }
}

View on GitHub (pinned to 766fd8bc89)

Solutions

  1. Check the store listing for which risks are populated for the track/arch
  2. Use risk=stable (or omit; handle defaults to a stable-style lookup with arch=amd64) unless you know the risk exists
  3. Fix the risk spelling to one of stable, candidate, beta, edge
  4. Release the snap to the desired risk via `snapcraft release`

Example fix

// before
/badge/snapcraft-version/my-snap?track=latest&risk=edge
// after
/badge/snapcraft-version/my-snap?track=latest&risk=stable
Defensive patterns

Strategy: try-catch

Validate before calling

const risks = ['stable','candidate','beta','edge'];
if (risk && !risks.includes(risk)) throw new Error(`invalid risk: ${risk}`);
// also check store channel-map contains track/arch + risk before calling

Type guard

const isRisk = (r) => !r || ['stable','candidate','beta','edge'].includes(r);

Try / catch

try {
  return await getSnapcraftVersion({ package: name, track, risk, arch });
} catch (err) {
  if (err prettyMessage === 'risk not found') return getSnapcraftVersion({ package: name, track, risk: 'stable', arch });
  throw err;
}

Prevention

When it happens

Trigger: Calling /snapcraft-version with `risk=edge` (or candidate/beta) when that track only publishes to stable, for the requested arch/track combination.

Common situations: Requesting 'edge' for a snap that never publishes edge builds; misspelling risk names ('stable' vs 'Stable'); assuming all four risks exist for every 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/66ec77c74471ef8d. Report an issue: GitHub.