hashicorp/terraform · error

Destroy discarded.

Error message

Destroy discarded.

What it means

An Attribute must define exactly one shape for its value: either a primitive/collection Type, or a NestedType (structural object). When both Type is cty.NilType and NestedType is nil, the attribute has no type at all and cannot hold a value, so validation fails.

Source

Thrown at internal/backend/remote/backend_common.go:27

	"errors"
	"fmt"
	"io"
	"math"
	"strconv"
	"strings"
	"time"

	tfe "github.com/hashicorp/go-tfe"

	"github.com/hashicorp/terraform/internal/backend/backendrun"
	"github.com/hashicorp/terraform/internal/logging"
	"github.com/hashicorp/terraform/internal/plans"
	"github.com/hashicorp/terraform/internal/terraform"
)

var (
	errApplyDiscarded   = errors.New("Apply discarded.")
	errDestroyDiscarded = errors.New("Destroy discarded.")
	errRunApproved      = errors.New("approved using the UI or API")
	errRunDiscarded     = errors.New("discarded using the UI or API")
	errRunOverridden    = errors.New("overridden using the UI or API")
)

var (
	backoffMin = 1000.0
	backoffMax = 3000.0

	runPollInterval = 3 * time.Second
)

// backoff will perform exponential backoff based on the iteration and
// limited by the provided min and max (in milliseconds) durations.
func backoff(min, max float64, iter int) time.Duration {
	backoff := math.Pow(2, float64(iter)/5) * min
	if backoff > max {
		backoff = max

View on GitHub (pinned to d32a084675)

Solutions

  1. Set Type to a concrete cty type (e.g. cty.String, cty.List(cty.Number)).
  2. Alternatively set NestedType to a *configschema.Object for a structural attribute.
  3. Ensure not both are set simultaneously (that triggers a separate Type-and-NestedType conflict).

Example fix

// before
"name": { Optional: true },
// after
"name": { Type: cty.String, Optional: true },
Defensive patterns

Strategy: validation

Validate before calling

// Require exactly one of Type or NestedType.
func hasTypeOrNestedType(a *configschema.Attribute) bool {
    return a != nil && (a.Type != cty.NilType || a.NestedType != nil)
}

Type guard

func exactlyOneShape(t cty.Type, nt *configschema.Object) bool {
    return (t != cty.NilType) != (nt != nil)
}

Prevention

When it happens

Trigger: An Attribute literal omitting both Type and NestedType. Guard at internal_validate.go:159 is `a.Type == cty.NilType && a.NestedType == nil`.

Common situations: Authoring an attribute and forgetting the type; refactoring that clears Type while a NestedType branch is also not set; copy-paste of a stub attribute.

Related errors


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