badges/shields · error · InvalidResponse

invalid rank

Error message

invalid rank

What it means

Thrown in GemRankService.handle when the BestGems API response does not yield a usable ranking value. The service reads json[0].total_ranking (for 'rt') or json[0].daily_ranking, and if rank == null an InvalidResponse 'invalid rank' is thrown.

Source

Thrown at services/gem/gem-rank.service.js:80

    if (period === 'rt') {
      endpoint = 'total_ranking.json'
      schema = totalSchema
    } else {
      endpoint = 'daily_ranking.json'
      schema = dailySchema
    }

    return this._requestJson({
      url: `http://bestgems.org/api/v1/gems/${gem}/${endpoint}`,
      schema,
    })
  }

  async handle({ period, gem }) {
    const json = await this.fetch({ period, gem })
    const rank = period === 'rt' ? json[0].total_ranking : json[0].daily_ranking
    if (rank == null) {
      throw new InvalidResponse({ prettyMessage: 'invalid rank' })
    }
    return this.constructor.render({ period, rank })
  }
}

View on GitHub (pinned to 766fd8bc89)

Solutions

  1. Confirm the gem is ranked at bestgems.org for the requested period
  2. Use the correct period token ('rt' for realtime total, 'dw' for daily)
  3. Check the BestGems API response for the gem to see if ranking fields are present
  4. Treat as transient upstream flakiness and retry later if BestGems was recently updated

Example fix

// before
/gem/rtd/my-unranked-gem
// after
/gem/rtd/rails  // use a ranked gem, or handle absence
Defensive patterns

Strategy: try-catch

Validate before calling

const data = await fetch(`https://bestgems.org/api/v1/gems/${gem}/${period === 'rt' ? 'total_ranking' : 'daily_ranking'}.json`).then(r => r.json());if (!Array.isArray(data) || data[0]?.[period === 'rt' ? 'total_ranking' : 'daily_ranking'] == null) { console.warn('gem is unranked'); }

Type guard

const hasRank = (json, period) => Array.isArray(json) && json.length > 0 && json[0]?.[period === 'rt' ? 'total_ranking' : 'daily_ranking'] != null;

Try / catch

try { return await gemRankBadge({ period, gem }); } catch (e) { if (String(e.message).includes('invalid rank')) { return renderBadge('unranked'); } throw e; }

Prevention

When it happens

Trigger: Requesting a gem rank badge where the upstream BestGems API returns an empty array, an array whose first element lacks the expected ranking field, or null ranking for that gem/period combination.

Common situations: Very new or very obscure gems that are unranked in BestGems; BestGems API schema changes or downtime returning malformed payloads; wrong period token (only 'rt' and 'dw' are supported) causing the wrong field to be read.

Related errors


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