Resolving "version already exists" error in Terraform Registry for pull requests

When using Spacelift's Terraform Registry with push policies to handle module versions for pull requests, you may encounter an error like:

version "99.99.99" already exists for terraform-module (commit: abc123)

This error occurs when your push policy assigns a version number that has already been created for the module, even during pull request testing.

Root Cause

This issue was present in Spacelift self-hosted versions prior to 3.0.0, where the system would check for existing versions even during proposed runs (pull requests). The version check has been removed in newer versions.

Solutions

Option 1: Upgrade Spacelift (Recommended)

If you're using Spacelift self-hosted version 2.6.0 or earlier, upgrade to version 3.0.0 or later. This version includes a fix that disables the version check for proposed runs, allowing pull requests to reuse version numbers without conflicts.

To check your current version:

  1. Click on your profile icon in the bottom left

  2. Select "Account details"

  3. Look for "Self-hosted version" in the popup

Option 2: Modify Push Policy (Temporary Workaround)

If you cannot upgrade immediately, you can work around this issue by removing the track block from your push policy:

Original policy with tracking:

package spacelift

module_version := version {
  version := trim_prefix(input.push.tag, "v")
  not propose
}

module_version := "99.99.99" {
  propose
}

propose {
  not is_null(input.pull_request)
}

track {
  module_version != ""
  input.push.branch == input.module.branch
}

Modified policy without tracking:

package spacelift

module_version := version {
  version := trim_prefix(input.push.tag, "v")
  not propose
}

module_version := "99.99.99" {
  propose
}

propose {
  not is_null(input.pull_request)
}

After removing the track block:

  1. Delete any existing problematic versions (like "99.99.99") from the Spacelift UI

  2. Save the updated policy

  3. Test with a new pull request

Important Notes

  • Without the track block, tracked runs will never create actual module versions

  • This allows you to reuse hardcoded version numbers in proposed runs without conflicts

  • The .spacelift/config.yml file is still required as it defines the test cases that run during pull requests

  • Pull requests run init, plan, apply, and destroy operations, not tofu init, validate, and test