{"record":{"id":"66ec77c74471ef8d","repo":"badges/shields","slug":"risk-not-found-66ec77","errorCode":null,"errorMessage":"risk not found","messagePattern":"risk not found","errorType":"exception","errorClass":"NotFound","httpStatus":null,"severity":"warning","filePath":"services/snapcraft/snapcraft-version.service.js","lineNumber":80,"sourceCode":"  static transform(apiData, track, risk, arch) {\n    const channelMap = apiData['channel-map']\n    let filteredChannelMap = channelMap.filter(\n      ({ channel }) => channel.architecture === arch,\n    )\n    if (filteredChannelMap.length === 0) {\n      throw new NotFound({ prettyMessage: 'arch not found' })\n    }\n    filteredChannelMap = filteredChannelMap.filter(\n      ({ channel }) => channel.track === track,\n    )\n    if (filteredChannelMap.length === 0) {\n      throw new NotFound({ prettyMessage: 'track not found' })\n    }\n    filteredChannelMap = filteredChannelMap.filter(\n      ({ channel }) => channel.risk === risk,\n    )\n    if (filteredChannelMap.length === 0) {\n      throw new NotFound({ prettyMessage: 'risk not found' })\n    }\n\n    return filteredChannelMap[0]\n  }\n\n  async handle({ package: packageName, track, risk }, { arch = 'amd64' }) {\n    const parsedData = await this.fetch(versionSchema, { packageName })\n\n    // filter results by track, risk and arch\n    const { version } = this.constructor.transform(\n      parsedData,\n      track,\n      risk,\n      arch,\n    )\n    return this.constructor.render({ version })\n  }\n}","sourceCodeStart":62,"sourceCodeEnd":98,"githubUrl":"https://github.com/badges/shields/blob/766fd8bc89a90b8534dc573ab72dec30215ab1ec/services/snapcraft/snapcraft-version.service.js#L62-L98","documentation":"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.","triggerScenarios":"Calling /snapcraft-version with `risk=edge` (or candidate/beta) when that track only publishes to stable, for the requested arch/track combination.","commonSituations":"Requesting 'edge' for a snap that never publishes edge builds; misspelling risk names ('stable' vs 'Stable'); assuming all four risks exist for every track.","solutions":["Check the store listing for which risks are populated for the track/arch","Use risk=stable (or omit; handle defaults to a stable-style lookup with arch=amd64) unless you know the risk exists","Fix the risk spelling to one of stable, candidate, beta, edge","Release the snap to the desired risk via `snapcraft release`"],"exampleFix":"// before\n/badge/snapcraft-version/my-snap?track=latest&risk=edge\n// after\n/badge/snapcraft-version/my-snap?track=latest&risk=stable","handlingStrategy":"try-catch","validationCode":"const risks = ['stable','candidate','beta','edge'];\nif (risk && !risks.includes(risk)) throw new Error(`invalid risk: ${risk}`);\n// also check store channel-map contains track/arch + risk before calling","typeGuard":"const isRisk = (r) => !r || ['stable','candidate','beta','edge'].includes(r);","tryCatchPattern":"try {\n  return await getSnapcraftVersion({ package: name, track, risk, arch });\n} catch (err) {\n  if (err prettyMessage === 'risk not found') return getSnapcraftVersion({ package: name, track, risk: 'stable', arch });\n  throw err;\n}","preventionTips":["Only request risks you confirmed exist for the snap's track/arch","Keep risk names lowercase exactly as the store uses them","Fall back to stable when the requested risk is absent"],"tags":["snapcraft","not-found","risk","channel"],"backgroundTag":"resource-not-found","analyzedSha":"766fd8bc89a90b8534dc573ab72dec30215ab1ec","analyzedAt":"2026-08-30T01:40:27.499Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}