hashicorp/terraform · error
state name not allow to be empty
Error message
state name not allow to be empty
What it means
Backend.client(name) builds a remoteClient whose stateFile and lockFile are derived from the name. It rejects empty or whitespace-only names with strings.TrimSpace(name) == "" because the resulting object key would be malformed.
Solutions
- Pass a non-empty workspace name.
- Use `terraform workspace new/select <name>` with a valid, non-empty name.
Defensive patterns
Strategy: validation
Validate before calling
// Reject empty workspace names before invoking the backend.
func safeClient(b *Backend, name string) (*remoteClient, error) {
if strings.TrimSpace(name) == "" {
return nil, fmt.Errorf("state name not allow to be empty")
}
return b.client(name)
} Type guard
// isValidWorkspaceName reports whether name is usable for the COS backend.
func isValidWorkspaceName(name string) bool {
return strings.TrimSpace(name) != ""
} Prevention
- Always pass a concrete workspace name from upstream code.
- Use terraform workspace new/select with a non-empty name.
- Lint automation that constructs workspace names to forbid empty.
- Unit-test name plumbing when integrating the backend.
When it happens
Trigger: b.client("") or b.client(" ") invoked from DeleteWorkspace/StateMgr.
Common situations: Bug in workspace-name plumbing upstream; a script calling the backend API with an empty workspace name; a workspace created with an empty name through some unsupported path.
Related errors
- default state is not allowed to be deleted
- acl value invalid, expected
- Error creating workspace
- Failed to lock cos state
- Invalid URL: must be
AI-assisted analysis of hashicorp/terraform@d32a084675 (2026-08-11).
Data as JSON: /api/errors/2ca56847af02ca14.
Report an issue: GitHub.
Appendix: source
Thrown at internal/backend/remote-state/cos/backend_state.go:156
if err := stateMgr.PersistState(nil); err != nil {
err = lockUnlock(err)
return nil, diags.Append(err)
}
}
// Unlock, the state should now be initialized
if err := lockUnlock(nil); err != nil {
return nil, diags.Append(err)
}
}
return stateMgr, diags
}
// client returns a remoteClient for the named state.
func (b *Backend) client(name string) (*remoteClient, error) {
if strings.TrimSpace(name) == "" {
return nil, fmt.Errorf("state name not allow to be empty")
}
return &remoteClient{
cosContext: b.cosContext,
cosClient: b.cosClient,
tagClient: b.tagClient,
bucket: b.bucket,
stateFile: b.stateFile(name),
lockFile: b.lockFile(name),
encrypt: b.encrypt,
acl: b.acl,
}, nil
}
// stateFile returns state file path by name
func (b *Backend) stateFile(name string) string {
if name == backend.DefaultStateName {
return path.Join(b.prefix, b.key)View on GitHub (pinned to d32a084675)