Budibase/budibase · error

Github latest release url not found

Error message

Github latest release url not found

What it means

fetchLatestRelease queries the GitHub latest-release API for a plugin's origin repository and looks for a downloadable asset with content type application/gzip (the plugin tarball). If no such asset exists in the release, it throws this error.

Source

Thrown at packages/server/src/sdk/plugins/update.ts:103

async function fetchLatestRelease(
  repo: string,
  token: string
): Promise<ReleaseDetails | null> {
  const url = `${GITHUB_API_ROOT}/${repo}/releases/latest`
  const headers = headersForRequest(token)
  const response = await fetch(url, { headers })

  if (response.status === 404) {
    return null
  }

  const data = await response.json()
  const tarballAsset = (data.assets || []).find(
    (asset: any) => asset?.content_type === "application/gzip"
  )
  const tarballUrl = tarballAsset?.browser_download_url
  if (!tarballUrl) {
    throw new Error("Github latest release url not found")
  }
  const version = normaliseVersion(data.tag_name) || normaliseVersion(data.name)
  if (!version) {
    throw new Error("Github release version not found")
  }
  return {
    version,
    tagName: data.tag_name,
    name: data.name,
    htmlUrl: data.html_url,
    publishedAt: data.published_at,
    tarballUrl,
    etag: response.headers.get("etag") || undefined,
    body: data.body,
  }
}

function buildUpdateInfo(

View on GitHub (pinned to a81a902e9a)

Solutions

  1. Ask the plugin maintainer to upload a .tar.gz asset (with gzip content type) to the GitHub release.
  2. Point the plugin origin at a release/tag that contains a proper tarball asset.
  3. Pin the plugin to a known-good version instead of tracking 'latest'.
  4. Check the release's assets via `gh release view <tag> --json assets` to confirm what is published.

Example fix

// before
gh release create v1.0.0  (no assets uploaded)
// after
gh release create v1.0.0 plugin-1.0.0.tar.gz
Defensive patterns

Strategy: fallback

Validate before calling

const release = await fetch(latestUrl).then(r => r.json())
const hasTarball = (release.assets || []).some(a => a.content_type === "application/gzip")
if (!hasTarball) throw new Error("No gzip tarball asset on latest release")

Type guard

const hasGzipAsset = (r: { assets?: { content_type?: string }[] }): boolean => (r.assets ?? []).some(a => a?.content_type === "application/gzip")

Try / catch

try {
  rel = await fetchLatestRelease(origin)
} catch {
  rel = await getFallbackPinnedRelease(origin) // last known-good version
}

Prevention

When it happens

Trigger: Checking a plugin for updates when the latest GitHub release has no .tar.gz/gzip asset, or the asset's content_type field is set to something else (e.g. application/x-tar or application/octet-stream).

Common situations: Plugin maintainers published a release with only source archives (auto-generated 'Source code (zip/tar.gz)' have no content_type asset entry) rather than an uploaded tarball; release assets were deleted; private repos returning a release without assets.

Related errors


AI-assisted analysis of Budibase/budibase@a81a902e9a (2026-08-29). Data as JSON: /api/errors/2213efec5a0504ec. Report an issue: GitHub.