hashicorp/terraform · error
cannot delete default state
Error message
cannot delete default state
What it means
In NestingSingle mode MinItems and MaxItems must be equal, because NestingSingle permits exactly zero or one instance. Mismatched values (e.g. MinItems=0, MaxItems=1) are ambiguous and rejected. This is checked first in the NestingSingle case before the 0-or-1 range check.
Solutions
- If the block is optional, set both MinItems: 0 and MaxItems: 0.
- If the block is required, set both MinItems: 1 and MaxItems: 1.
- Switch to NestingList/NestingSet if you genuinely need a min/max range.
Example fix
// before
"settings": { Nesting: configschema.NestingSingle, MinItems: 0, MaxItems: 1 },
// after (optional single)
"settings": { Nesting: configschema.NestingSingle, MinItems: 0, MaxItems: 0 }, Defensive patterns
Strategy: validation
Validate before calling
// For NestingSingle, require equal counts.
func validSingleCounts(nb *configschema.NestedBlock) bool {
return nb.Nesting != configschema.NestingSingle || nb.MinItems == nb.MaxItems
} Type guard
func singleCountsMatch(min, max int) bool { return min == max } Prevention
- For NestingSingle use (0,0) for optional or (1,1) for required.
- Avoid copying NestingList min/max values into a NestingSingle block.
- Prefer NestingList when you need a min/max range.
When it happens
Trigger: A NestedBlock with Nesting: NestingSingle where MinItems != MaxItems (e.g. MinItems: 0, MaxItems: 1). Guard at internal_validate.go:76 is `blockS.MinItems != blockS.MaxItems`.
Common situations: Treating NestingSingle like NestingList and trying to set an optional/required pair; copying NestingList defaults into a NestingSingle block.
Related errors
- consul lock was lost
- execution halted
- failed to append certs
- missing state name
- workspaces not supported
AI-assisted analysis of hashicorp/terraform@d32a084675 (2026-08-11).
Data as JSON: /api/errors/0b118ad563d60459.
Report an issue: GitHub.
Appendix: source
Thrown at internal/backend/local/backend.go:248
}
// DeleteWorkspace removes a workspace.
//
// The "default" workspace cannot be removed.
func (b *Local) DeleteWorkspace(name string, force bool) tfdiags.Diagnostics {
var diags tfdiags.Diagnostics
// If we have a backend handling state, defer to that.
if b.Backend != nil {
return b.Backend.DeleteWorkspace(name, force)
}
if name == "" {
return diags.Append(errors.New("empty state name"))
}
if name == backend.DefaultStateName {
return diags.Append(errors.New("cannot delete default state"))
}
delete(b.states, name)
err := os.RemoveAll(filepath.Join(b.stateWorkspaceDir(), name))
if err != nil {
return diags.Append(fmt.Errorf("error deleting workspace %s: %w", name, err))
}
return diags
}
func (b *Local) StateMgr(name string) (statemgr.Full, tfdiags.Diagnostics) {
var diags tfdiags.Diagnostics
// If we have a backend handling state, delegate to that.
if b.Backend != nil {
return b.Backend.StateMgr(name)
}View on GitHub (pinned to d32a084675)