cloudflare/cloudflared · error · Exception

Tag {} not found

Error message

Tag {} not found

What it means

assert_tag_exists verifies that the newest tag on the GitHub repository matches the release version being published; if the repo has no tags at all, or tags[0].name != version, it raises this exception. It assumes get_tags() returns tags sorted with the most recent first, so a version that exists but is not the latest tag will also fail.

Source

Thrown at github_release.py:61

    response = requests.put(
            BASE_KV_URL + account + "/storage/kv/namespaces/" + namespace + "/values/" + key,
            headers=headers,
            data=pkg_hash
    )

    if response.status_code != 200:
        jsonResponse = response.json()
        errors = jsonResponse["errors"]
        if len(errors) > 0:
            raise Exception("failed to upload checksum: {0}", errors[0])



def assert_tag_exists(repo, version):
    """ Raise exception if repo does not contain a tag matching version """
    tags = repo.get_tags()
    if not tags or tags[0].name != version:
        raise Exception("Tag {} not found".format(version))


def get_or_create_release(repo, version, dry_run=False, is_draft=False):
    """
    Get a Github Release matching the version tag or create a new one.
    If a conflict occurs on creation, attempt to fetch the Release on last time
    """
    try:
        release = repo.get_release(version)
        logging.info("Release %s found", version)
        return release
    except UnknownObjectException:
        logging.info("Release %s not found", version)

    # We don't want to create a new release tag if one doesn't already exist
    assert_tag_exists(repo, version)

    if dry_run:

View on GitHub (pinned to 2253eeeb25)

Solutions

  1. Ensure the tag is created and pushed to the remote before running the release script (git tag vX.Y.Z && git push origin vX.Y.Z).
  2. Verify the version argument matches the tag name exactly, including the 'v' prefix.
  3. Instead of relying on tags[0], iterate all tags to check membership: if not any(t.name == version for t in tags).
  4. Re-run the release pipeline after the tag is present.

Example fix

// before
if not tags or tags[0].name != version:
    raise Exception("Tag {} not found".format(version))
// after
if not any(tag.name == version for tag in tags):
    raise Exception("Tag {} not found".format(version))
Defensive patterns

Strategy: validation

Validate before calling

tags = repo.get_tags()
if not any(t.name == version for t in tags):
    raise SystemExit(f"tag {version} missing on remote; push it before releasing")

Try / catch

try:
    release = get_or_create_release(repo, version)
except Exception as e:
    logging.error("release aborted: %s", e)
    sys.exit(1)

Prevention

When it happens

Trigger: Calling get_or_create_release (which calls assert_tag_exists) with a version that was never tagged, a version string that does not exactly match the tag name (e.g. missing 'v' prefix: '1.2.3' vs tag 'v1.2.3'), or when the tag exists but is older than another tag.

Common situations: Forgetting to run 'git push --tags' before the release job; typos in --release-version; projects where CI tags the repo after the release step instead of before; repos where get_tags() pagination hides the requested tag.

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.


AI-assisted analysis of cloudflare/cloudflared@2253eeeb25 (2026-09-06). Data as JSON: /api/errors/fbe94c2a451fcf73. Report an issue: GitHub.