{"record":{"id":"bffe7dbe7d8a0a8d","repo":"badges/shields","slug":"no-packages-found","errorCode":null,"errorMessage":"no packages found","messagePattern":"no packages found","errorType":"exception","errorClass":"NotFound","httpStatus":404,"severity":"error","filePath":"services/f-droid/f-droid.service.js","lineNumber":78,"sourceCode":"    baseUrl = baseUrl.replace(/\\/$/, '')\n    const url = `${baseUrl}/api/v1/packages/${appId}`\n    return this._requestJson({\n      schema,\n      url,\n      httpErrors: {\n        403: 'app not found',\n        404: 'app not found',\n      },\n    })\n  }\n\n  transform({ json, suggested }) {\n    const svc = suggested && json.suggestedVersionCode\n    const packages = (json.packages || []).filter(\n      ({ versionCode }) => !svc || versionCode <= svc,\n    )\n    if (packages.length === 0) {\n      throw new NotFound({ prettyMessage: 'no packages found' })\n    }\n    const version = packages.reduce((a, b) =>\n      a.versionCode > b.versionCode ? a : b,\n    ).versionName\n    return { version }\n  }\n\n  async handle(\n    { appId },\n    { baseUrl = 'https://f-droid.org', include_prereleases: includePre },\n  ) {\n    const json = await this.fetch({ baseUrl, appId })\n    const suggested = includePre === undefined\n    const { version } = this.transform({ json, suggested })\n    return renderVersionBadge({ version })\n  }\n}\n","sourceCodeStart":60,"sourceCodeEnd":96,"githubUrl":"https://github.com/badges/shields/blob/766fd8bc89a90b8534dc573ab72dec30215ab1ec/services/f-droid/f-droid.service.js#L60-L96","documentation":"The F-Droid service fetches package metadata and filters json.packages down to entries whose versionCode is at or below the suggestedVersionCode (when one is present). If no packages remain after filtering, it throws NotFound with prettyMessage 'no packages found', meaning F-Droid reports no usable package builds for this app.","triggerScenarios":"Requesting an F-Droid version badge for an app whose packages array is empty or whose packages all have versionCodes above suggestedVersionCode (e.g. all builds marked unstable/newer than suggested).","commonSituations":"Newly published apps with no package builds yet; apps where every package was archived or is a pre-release above the suggested version; typos in the app id returning a metadata stub with no packages.","solutions":["Verify the app id in the F-Droid index and confirm it has published packages","Check the F-Droid index JSON for the app to see whether packages is empty or filtered out by suggestedVersionCode","Pin/choose a different F-Droid mirror or index that includes the builds","Wait for F-Droid to publish a build within the suggested version range"],"exampleFix":"// before\n/badge/f-droid/v/org.fdroid.wrongid\n// after\n/badge/f-droid/v/org.fdroid.fdroid","handlingStrategy":"validation","validationCode":"async function fdroidHasPackages(appId) {\n  const res = await fetch(`https://f-droid.org/api/v1/packages/${appId}`)\n  if (!res.ok) return false\n  const json = await res.json()\n  return Array.isArray(json.packages) && json.packages.length > 0\n}\n// verify before rendering the badge","typeGuard":"function hasPackages(json) {\n  return Array.isArray(json.packages) && json.packages.length > 0\n}","tryCatchPattern":"try {\n  const badge = await getFDroidVersionBadge(appId)\n} catch (e) {\n  if (e.prettyMessage === 'no packages found') {\n    renderPlaceholderBadge('not published')\n  } else throw e\n}","preventionTips":["Confirm the exact F-Droid app id (package name) before configuring the badge","Check the F-Droid index JSON for the app to confirm packages exist within the suggested version range","Expect this error for freshly published or fully archived apps","Monitor badge health so schema/index changes surface quickly"],"tags":["f-droid","not-found","version-badge","android"],"backgroundTag":"package-not-found-in-registry","analyzedSha":"766fd8bc89a90b8534dc573ab72dec30215ab1ec","analyzedAt":"2026-08-30T01:40:27.499Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}