badges/shields · error · NotFound

coverage not found

Error message

coverage not found

What it means

NotFound thrown when the Scrutinizer metric value for scrutinizer.test_coverage comes back empty for the requested project/branch. The transform chain succeeded (branch info and index exist) but there is no coverage number, so a coverage badge cannot be rendered.

Source

Thrown at services/scrutinizer/scrutinizer-coverage.service.js:54

    label: 'coverage',
  }

  static render({ coverage }) {
    return {
      message: `${coverage.toFixed(0)}%`,
      color: scale(coverage),
    }
  }

  transform({ json, branch }) {
    const { value: rawCoverage } = this.transformBranchInfoMetricValue({
      json,
      branch,
      metric: 'scrutinizer.test_coverage',
    })

    if (!rawCoverage) {
      throw new NotFound({ prettyMessage: 'coverage not found' })
    }

    return { coverage: rawCoverage * 100 }
  }

  async makeBadge({ vcs, slug, branch }) {
    const json = await this.fetch({ schema, vcs, slug })
    const { coverage } = this.transform({ json, branch })
    return this.constructor.render({ coverage })
  }
}

class ScrutinizerCoverage extends ScrutinizerCoverageBase {
  static route = {
    base: 'scrutinizer/coverage',
    pattern: ':vcs(g|b)/:user/:repo/:branch*',
  }

View on GitHub (pinned to 766fd8bc89)

Solutions

  1. Configure coverage collection in .scrutinizer.yml (coverage: enabled, proper test commands) so scrutinizer.test_coverage is reported
  2. Verify on the Scrutinizer project page that a coverage percentage is displayed for that branch
  3. Re-run the analysis after enabling coverage and refresh the badge
  4. If coverage genuinely doesn't exist for this repo, don't use the coverage badge — use the build/quality badge instead

Example fix

// before (.scrutinizer.yml without coverage)
checks:
  javascript: true
// after
build:
  tests:
    override:
      - command: npm test
        coverage:
          file: coverage/lcov.info
          format: lcov
Defensive patterns

Strategy: try-catch

Validate before calling

// Check that coverage is reported before using the coverage badge
async function hasCoverage(vcs, slug) {
  const res = await fetch(`https://scrutinizer-ci.com/api/repositories/${vcs}/${slug}`)
  const repo = await res.json()
  const app = Object.values(repo.applications || {})[0]
  const mv = app && app.index && app.index._embedded && app.index._embedded.project && app.index._embedded.project.metric_values
  return Boolean(mv && mv['scrutinizer.test_coverage'] != null)
}

Type guard

function hasCoverageMetric(metricValues) {
  return metricValues != null && metricValues['scrutinizer.test_coverage'] != null
}

Try / catch

try {
  const badge = await fetchBadgeUrl(scrutinizerCoverageUrl)
} catch (e) {
  if (/coverage not found/.test(e.message)) {
    console.warn('No coverage reported by Scrutinizer; omitting coverage badge')
  } else throw e
}

Prevention

When it happens

Trigger: Requesting a Scrutinizer coverage badge for a project/branch where the analysis completed but reported no test coverage metric — e.g. no tests detected by Scrutinizer, coverage not configured in .scrutinizer.yml, or metric_values missing scrutinizer.test_coverage.

Common situations: Repo analyzed but the test command/coverage reporter is not configured; new branch analyzed before CI uploaded coverage; project uses a CI setup Scrutinizer cannot collect coverage from.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


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