hashicorp/terraform · critical
unexpected empty message for init message code: %s
Error message
unexpected empty message for init message code: %s
What it means
This panic fires in InitHuman.prepareMessage when an InitMessageCode resolves to a MessageRegistry entry whose HumanValue is the empty string. The registry must have a human-readable template for every code, so an empty HumanValue means the registry was extended with a code but no human text.
Source
Thrown at internal/command/views/init.go:227
// prints the formatted message to the stdout stream.
func (v *InitHuman) print(message string) {
message = v.view.colorize.Color(strings.TrimSpace(message))
v.view.streams.Println(message)
}
// prepareMessage retrieves a message template matching the InitMessageCode and
// returns a formatted string made using the template and param argument(s).
//
// As this is implemented on InitHuman the human message template is used.
func (v *InitHuman) prepareMessage(messageCode InitMessageCode, params ...any) string {
message, ok := MessageRegistry[messageCode]
if !ok {
// display the message code as fallback if not found in the message registry
return string(messageCode)
}
if message.HumanValue == "" {
panic("unexpected empty message for init message code: " + string(messageCode))
}
return fmt.Sprintf(message.HumanValue, params...)
}
// The InitJSON implementation renders streaming JSON logs, suitable for
// integrating with other software.
type InitJSON struct {
view *JSONView
}
var (
_ Init = (*InitJSON)(nil)
_ ProviderInstallationLogger = (*InitJSON)(nil)
)
func (v *InitJSON) Diagnostics(diags tfdiags.Diagnostics) {
v.view.Diagnostics(diags)View on GitHub (pinned to d32a084675)
Solutions
- Search MessageRegistry in views/init.go for the code printed in the panic; fill in a non-empty HumanValue template.
- Add a test that iterates all InitMessageCode values and asserts MessageRegistry[code].HumanValue != "".
- If the code should not have a human form, do not register it (or restructure so prepareMessage is never called for it).
Example fix
// before
MessageRegistry[InitSomeNewCode] = InitMessage{
HumanValue: "",
JSONValue: "some json template",
}
// after
MessageRegistry[InitSomeNewCode] = InitMessage{
HumanValue: "Initializing some new thing...",
JSONValue: "some json template",
} Defensive patterns
Strategy: validation
Validate before calling
// Validate the registry on init.
for code, msg := range MessageRegistry {
if msg.HumanValue == "" {
panic("registry missing HumanValue for " + string(code)) // fail fast at boot
}
} Type guard
// n/a — string emptiness check
Prevention
- Add an init() or test that asserts MessageRegistry[code].HumanValue != "" for every code.
- Code-review new InitMessageCode additions for both HumanValue and JSONValue fields.
- Treat the registry as a typed struct so omitted fields surface at compile time.
When it happens
Trigger: `terraform init` (human output) emits a registered InitMessageCode whose MessageRegistry entry has HumanValue="". Reached when a maintainer adds a code to the InitMessageCode type and a registry row, but leaves HumanValue blank, and init then tries to display it.
Common situations: A maintainer adds a new init message code and forgets to fill in (or accidentally empties) the HumanValue field. Triggered the first time init renders that message during a normal `terraform init`.
Related errors
- unknown view type %v
- unknown view type %v
- unknown view type %v
- unknown view type %v
- unknown view type %v
AI-assisted analysis of hashicorp/terraform@d32a084675 (2026-08-11).
Data as JSON: /api/errors/cbb64010613c51bc.
Report an issue: GitHub.