badges/shields · warning · NotFound

no finished builds

Error message

no finished builds

What it means

The ReadTheDocs badge throws NotFound 'no finished builds' when the API returns builds but none has state.code === 'finished'. The badge needs a completed build to compute passing/failing, so pending/errored/cancelled-only build lists yield this error.

Source

Thrown at services/readthedocs/readthedocs.service.js:96

          url: `https://app.readthedocs.org/api/v3/projects/${encodeURIComponent(project)}/versions/${encodeURIComponent(version)}/builds/`,
          options: {
            searchParams: {
              fields: 'state,success',
              limit: 10,
              running: false,
            },
          },
        },
        'Token',
      ),
    )
  }

  async handle({ project, version }) {
    const { results } = await this.fetch({ project, version })
    const build = results.find(({ state }) => state.code === 'finished')
    if (!build) {
      throw new NotFound({
        prettyMessage: 'no finished builds',
      })
    }
    return this.constructor.render({
      status: build.success ? 'passing' : 'failing',
    })
  }
}

View on GitHub (pinned to 766fd8bc89)

Solutions

  1. Wait for a build to finish on ReadTheDocs, then retry the badge
  2. Trigger a new build manually from the RTD project dashboard and verify it completes
  3. Confirm the version parameter matches an existing RTD version with completed builds

Example fix

// before
/badge/readthedocs/myproject/typo-branch   (never built)
// after
/badge/readthedocs/myproject/latest
Defensive patterns

Strategy: retry

Validate before calling

const api = await fetch(`https://readthedocs.org/api/v3/projects/${project}/versions/${version}/builds`)
const { results } = await api.json()
if (!results?.some(b => b.state?.code === 'finished')) throw new Error('no finished builds yet')

Type guard

function hasFinishedBuild(payload) {
  return Array.isArray(payload?.results) &&
    payload.results.some(b => b?.state?.code === 'finished')
}

Try / catch

try {
  return await service.handle({ project, version })
} catch (err) {
  if (err instanceof NotFound && err.prettyMessage === 'no finished builds') {
    return renderBadge({ label: 'docs', message: 'building' })
  }
  throw err
}

Prevention

When it happens

Trigger: Requesting a badge for a project/version that has only queued, building, cancelled, or errored builds; a version identifier that maps to builds that never completed.

Common situations: Freshly imported projects before the first successful build; a version name (e.g. 'latest' vs actual branch) whose builds never finish; RTDocs build failures during setup; temporarily unavailable builders.

Related errors


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