badges/shields · error · InvalidResponse

no coverage data available

Error message

no coverage data available

What it means

TeamCity coverage badge's `transform` extracts covered/total statistics from the TeamCity REST build statistics endpoint. When the statisticValue entries for the coverage counters are absent (undefined), it throws an InvalidResponse — not NotFound — with 'no coverage data available', meaning the build reported no coverage data at all.

Solutions

  1. Enable code coverage in the TeamCity build configuration (e.g. IDEA coverage or JaCoCo agent) and re-run the build
  2. Verify the buildId belongs to a successful, finished build that ran with coverage
  3. Confirm the `server` param points to the right TeamCity instance and the build exists there
  4. Inspect GET <server>/app/rest/builds/buildType:(id:<buildId>)/statistics to confirm coverage statistic keys exist

Example fix

// before
/badge/teamcity-coverage/MyBuildId?server=https://teamcity.example.com  // build has no coverage agent
// after: enable IDEA/JaCoCo coverage in the build config, re-run, then keep the same badge URL
Defensive patterns

Strategy: try-catch

Validate before calling

const stats = await fetch(`${server}/app/rest/builds/buildType:(id:${buildId})/statistics`, { headers }).then(r => r.json());
const hasCoverage = (stats?.property || []).some(p => /coverage/i.test(p.name));
if (!hasCoverage) throw new Error('build ran without coverage instrumentation');

Type guard

const hasCoverageStats = (json) => Array.isArray(json?.property) && json.property.some(p => /coverage/i.test(String(p.name)));

Try / catch

try {
  return await teamcityCoverage({ buildId, server });
} catch (err) {
  if (err message includes 'no coverage data available') {
    // render 'coverage unknown' badge; enable coverage in the build config
  } else throw err;
}

Prevention

When it happens

Trigger: Calling /teamcity-coverage/<buildId> (against `server`, default https://teamcity.jetbrains.com) where the finished build's /app/rest/builds/<locator>/statistics contains no coverage-related statistic values — e.g. builds whose tests run without coverage instrumentation.

Common situations: Build configuration without Java code coverage enabled (no IDEA coverage/jacoco agent); buildId points at a personal/failed/canceled build that produced no statistics; wrong TeamCity server URL so statistics come back empty for the locator; coverage counters renamed/missing in newer TeamCity.

Related errors


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

Appendix: source

Thrown at services/teamcity/teamcity-coverage.service.js:73

  }

  transform({ data }) {
    let covered, total

    for (const p of data.property) {
      if (p.name === 'CodeCoverageAbsSCovered') {
        covered = +p.value
      } else if (p.name === 'CodeCoverageAbsSTotal') {
        total = +p.value
      }

      if (covered !== undefined && total !== undefined) {
        const coverage = covered ? (covered / total) * 100 : 0
        return { coverage }
      }
    }

    throw new InvalidResponse({ prettyMessage: 'no coverage data available' })
  }

  async handle({ buildId }, { server = 'https://teamcity.jetbrains.com' }) {
    // JetBrains Docs: https://confluence.jetbrains.com/display/TCD18/REST+API#RESTAPI-Statistics
    const buildLocator = `buildType:(id:${buildId})`
    const apiPath = `app/rest/builds/${encodeURIComponent(
      buildLocator,
    )}/statistics`
    const data = await this.fetch({
      url: `${server}/${apiPath}`,
      schema: buildStatisticsSchema,
    })

    const { coverage } = this.transform({ data })
    return this.constructor.render({ coverage })
  }
}

View on GitHub (pinned to 766fd8bc89)