NousResearch/hermes-agent · error · Error

Extension "${id}" has no published versions.

Error message

Extension "${id}" has no published versions.

What it means

Thrown by resolveExtension() when the Marketplace returns a matching extension object but extension.versions[0] is missing. The query uses IncludeLatestVersionOnly (flags 914), so a healthy listing always carries at least one version; an empty one means the listing is in a broken or partial state on the gallery side.

Source

Thrown at apps/desktop/electron/vscode-marketplace.ts:113

async function resolveExtension(id) {
  const json = await queryGallery({
    // FilterType 7 = ExtensionName (the full publisher.extension id).
    filters: [{ criteria: [{ filterType: 7, value: id }], pageNumber: 1, pageSize: 1 }],
    // Flags: IncludeFiles | IncludeVersionProperties | IncludeAssetUri |
    // IncludeCategoryAndTags | IncludeLatestVersionOnly = 914.
    flags: 914
  })

  const extension = json?.results?.[0]?.extensions?.[0]

  if (!extension) {
    throw new Error(`Extension "${id}" was not found on the Marketplace.`)
  }

  const version = extension.versions?.[0]

  if (!version) {
    throw new Error(`Extension "${id}" has no published versions.`)
  }

  const asset = (version.files ?? []).find(file => file.assetType === VSIX_ASSET_TYPE)
  const vsixUrl = asset?.source

  if (!vsixUrl) {
    throw new Error(`Could not find a downloadable package for "${id}".`)
  }

  return { displayName: extension.displayName || id, vsixUrl }
}

/** POST an ExtensionQuery payload and return the parsed gallery response. */
async function queryGallery(payload, { maxBytes = 4 * 1024 * 1024 } = {}) {
  const body = JSON.stringify(payload)

  const raw = await request(GALLERY_QUERY_URL, {
    method: 'POST',

View on GitHub (pinned to c896c09c42)

Solutions

  1. Retry after a short delay with backoff — transient gallery states usually resolve within minutes.
  2. Verify the extension page on the Marketplace: if all versions were withdrawn, pin a different extension or handle the failure gracefully.
  3. If behind a proxy, confirm the full JSON body is received (content-length vs actual bytes).
  4. Cache the last-known-good vsixUrl so a temporary gallery gap does not break extension setup.

Example fix

// before
const ext = await resolveExtension(id)

// after
async function resolveWithRetry(id, attempts = 3) {
  for (let i = 0; i < attempts; i++) {
    try { return await resolveExtension(id) }
    catch (e) {
      if (!/no published versions/.test(e.message) || i === attempts - 1) throw e
      await new Promise(r => setTimeout(r, 5_000 * (i + 1)))
    }
  }
}
Defensive patterns

Strategy: retry

Try / catch

for (let attempt = 0; attempt < 3; attempt++) {
  try {
    return await resolveExtension(id)
  } catch (e) {
    const transient = e instanceof Error && e.message.includes('no published versions')
    if (!transient || attempt === 2) throw e
    await new Promise(r => setTimeout(r, 5_000 * (attempt + 1)))
  }
}

Prevention

When it happens

Trigger: queryGallery returns extensions[0] but extension.versions is undefined or [] — an extension unlisted mid-publish, gallery replication lag right after a version removal, or a stunted/truncated response from a proxy or CDN.

Common situations: Extension temporarily unpublished while a new version is validated; rare gallery inconsistency; corporate proxy truncating the JSON body so the versions field is lost.

Related errors


AI-assisted analysis of NousResearch/hermes-agent@c896c09c42 (2026-08-14). Data as JSON: /api/errors/c3d3ad718b24ef49. Report an issue: GitHub.