hashicorp/terraform · error

ErrInvalidRunID

ErrInvalidRunID

Error message

invalid run ID

What it means

Exported sentinel ErrInvalidRunID (cloudplan/saved_plan.go:14, code=ErrInvalidRunID). After unmarshalling a bookmark, Read checks the RunID: it must be non-empty AND start with "run-" (saved_plan.go:59). An empty run ID or one without the 'run-' prefix returns this error, indicating the file is not a valid cloud saved-plan bookmark.

Source

Thrown at internal/cloud/cloudplan/saved_plan.go:14

// Copyright IBM Corp. 2014, 2026
// SPDX-License-Identifier: BUSL-1.1
package cloudplan

import (
	"encoding/json"
	"errors"
	"io"
	"os"
	"strings"
)

var ErrInvalidRemotePlanFormat = errors.New("invalid remote plan format, must be 1")
var ErrInvalidRunID = errors.New("invalid run ID")
var ErrInvalidHostname = errors.New("invalid hostname")

type SavedPlanBookmark struct {
	RemotePlanFormat int    `json:"remote_plan_format"`
	RunID            string `json:"run_id"`
	Hostname         string `json:"hostname"`
}

func NewSavedPlanBookmark(runID, hostname string) SavedPlanBookmark {
	return SavedPlanBookmark{
		RemotePlanFormat: 1,
		RunID:            runID,
		Hostname:         hostname,
	}
}

func LoadSavedPlanBookmark(filepath string) (SavedPlanBookmark, error) {
	bookmark := SavedPlanBookmark{}

View on GitHub (pinned to d32a084675)

Solutions

  1. Regenerate the plan file with terraform plan -out=<file> against the cloud backend so a valid run-<id> is written.
  2. Do not hand-edit the bookmark; if you must migrate runs, reference the run via the UI/API and re-plan.
Defensive patterns

Strategy: validation

Validate before calling

func validRunID(id string) bool { return id != "" && strings.HasPrefix(id, "run-") }

Type guard

func isLikelyRunID(s string) bool {
    return strings.HasPrefix(s, "run-")
}

Try / catch

b, err := cloudplan.StateRead(path)
if err != nil {
    if errors.Is(err, cloudplan.ErrInvalidRunID) {
        // bookmark run_id is missing/malformed; regenerate the plan file
    }
}

Prevention

When it happens

Trigger: Reading a JSON bookmark whose `run_id` field is missing, empty, or malformed (e.g. a manually crafted file with `{"remote_plan_format":1,"hostname":"x","run_id":"abc"}` — no 'run-' prefix) — saved_plan.go:59 condition fires.

Common situations: Editing or templating a plan bookmark and stripping/altering the run_id. A corrupt or partial bookmark file. Using a file that is JSON but not an actual cloud plan bookmark.

Related errors


AI-assisted analysis of hashicorp/terraform@d32a084675 (2026-08-11). Data as JSON: /api/errors/80a119d097b1f88a. Report an issue: GitHub.