hashicorp/terraform · critical

missing message for InstallingProviderMessage init message c

Error message

missing message for InstallingProviderMessage init message code

What it means

StateMigrateHuman.Output (internal/command/views/state_migrate.go:166, implementing ProviderInstallationLogger) looks up the human message for a given InitMessageCode in the shared MessageRegistry (defined in internal/command/views/init.go:495). If the code is absent from the registry it panics 'missing message for InstallingProviderMessage init message code'.

Source

Thrown at internal/command/views/state_migrate.go:172

func (s *StateMigrateHuman) Log(message string, params ...any) {
	s.log(fmt.Sprintf(message, params...))
}

func (s *StateMigrateHuman) log(preparedMessage string) {
	msg := s.view.colorize.Color(strings.TrimSpace(preparedMessage))
	s.view.streams.Println(msg)
}

// Implements Spacer
func (s *StateMigrateHuman) Spacer() {
	s.view.Spacer()
}

// Implements ProviderInstallationLogger interface.
func (s *StateMigrateHuman) Output(code InitMessageCode, params ...any) {
	msg, ok := MessageRegistry[code]
	if !ok {
		panic("missing message for InstallingProviderMessage init message code")
	}
	s.Log(msg.HumanValue, params...)
}

// Implements ProviderInstallationLogger interface.
func (s *StateMigrateHuman) LogInstallStateStoreProviderStart(pAddr tfaddr.Provider, cons getproviders.VersionConstraints, storeType string) {
	consSuffix := ""
	if len(cons) > 0 {
		consSuffix = fmt.Sprintf(" (%s)", getproviders.VersionConstraintsString(cons))
	}
	params := []any{pAddr.ForDisplay(), consSuffix, storeType}
	msg := fmt.Sprintf(logInstallingStateStoreProviderStartMessageHuman, params...)
	s.log(msg)
}

// Implements StateStoreProviderTrustLogger interface.
func (s *StateMigrateHuman) LogInteractiveApproval() {
	s.log(logInteractiveApprovalMessageHuman)

View on GitHub (pinned to d32a084675)

Solutions

  1. Whenever you add a new InitMessageCode constant, add its InitMessage (HumanValue) to MessageRegistry in internal/command/views/init.go in the same commit.
  2. Search for all InitMessageCode constants and diff them against MessageRegistry keys to find unregistered codes.
  3. Add a unit test that iterates every InitMessageCode constant and asserts MessageRegistry[code] exists.
  4. As an end user this is an internal bug — report it with the state-migrate/init operation that triggered the panic.

Example fix

// before
msg, ok := MessageRegistry[code]
if !ok {
    panic("missing message for InstallingProviderMessage init message code")
}

// after (no-op + log instead of crashing)
msg, ok := MessageRegistry[code]
if !ok {
    log.Printf("[WARN] no message registered for init message code %q", code)
    return
}
Defensive patterns

Strategy: validation

Validate before calling

// Validate the code is registered before calling Output.
func isRegistered(code views.InitMessageCode) bool {
    _, ok := views.MessageRegistry[code]
    return ok
}
if !isRegistered(code) {
    return fmt.Errorf("unregistered init message code %q", code)
}

Prevention

When it happens

Trigger: Output is called with an InitMessageCode value not present in MessageRegistry — e.g. a new InitMessageCode constant added to init.go without a corresponding registry entry, or a caller passing an arbitrary/empty string cast as InitMessageCode.

Common situations: Adding a provider-install lifecycle message during state migration and forgetting to register it; a refactor that moves codes without moving registry entries; a typo when constructing the code.

Related errors


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