badges/shields · error · InvalidResponse

version not found

Error message

version not found

What it means

crates-base's getVersionObj looks up the full version object matching the chosen latest version number among response.versions; if none matches it throws InvalidResponse with 'version not found'. It is an internal consistency check: the crates.io response listed a latest version but did not include its detail object.

Source

Thrown at services/crates/crates-base.js:64

    return this._requestJson({
      schema,
      url,
      httpErrors: version ? { 400: 'invalid version' } : {},
    })
  }

  static getLatestVersion(response) {
    return response.crate.max_stable_version
      ? response.crate.max_stable_version
      : response.crate.max_version
  }

  static getVersionObj(response) {
    if (response.crate) {
      const version = this.getLatestVersion(response)
      const versionObj = response.versions.find(v => v.num === version)
      if (versionObj === undefined) {
        throw new InvalidResponse({ prettyMessage: 'version not found' })
      }
      return versionObj
    }
    return response.version
  }
}

class BaseCratesUserService extends BaseJsonService {
  static defaultBadgeData = { label: 'crates.io' }

  /**
   * Fetches data from the crates.io API.
   *
   * @param {object} options - The options for the request
   * @param {string} options.userId - The user ID.
   * @returns {Promise<object>} the JSON response from the API.
   */
  async fetch({ userId }) {

View on GitHub (pinned to 766fd8bc89)

Solutions

  1. Retry the badge request — crates.io may have returned a momentarily inconsistent response
  2. Check the crate on crates.io and confirm the latest version is listed with its details
  3. Verify the crate name spelling in the badge URL
  4. Report to the badge maintainers if crates.io consistently omits the version object
Defensive patterns

Strategy: retry

Validate before calling

function responseIsConsistent(res) {
  if (!res.crate) return true;
  const latest = res.crate.max_stable_version || res.crate.max_version || res.crate.newest_version;
  return latest == null || res.versions.some(v => v.num === latest);
}

Type guard

function hasMatchingVersionObj(res) {
  const v = res.crate && (res.crate.max_stable_version || res.crate.max_version);
  return !v || res.versions?.some(e => e.num === v);
}

Try / catch

try {
  const badge = await fetchBadge(`/crates/l/${crate}`);
} catch (e) {
  if (e.message.includes('version not found')) await retryWithBackoff(3);
  else throw e;
}

Prevention

When it happens

Trigger: getVersionObj receives a crates.io API response where response.crate exists, getLatestVersion picks a version (e.g. max_version or max_stable_version), but response.versions contains no entry with v.num === version.

Common situations: crates.io API changes or partial responses omitting version details, yanked versions filtered out, or transient upstream inconsistencies during republishing.

Related errors


AI-assisted analysis of badges/shields@766fd8bc89 (2026-08-30). Data as JSON: /api/errors/6ddf929a4c6411a3. Report an issue: GitHub.