hashicorp/terraform · critical
unknown view type
Error message
unknown view type %v
What it means
This panic fires in NewRefresh when arguments.ViewType is neither ViewJSON nor ViewHuman. The refresh switch has no case for ViewNone(0) or ViewRaw('R').
Solutions
- Set ViewType explicitly to arguments.ViewHuman or arguments.ViewJSON in any code/test calling NewRefresh.
- Add a case for any new ViewType to views/refresh.go:41 (and sibling New* switches).
- Cover with refresh_test.go.
Example fix
// before
r := arguments.Refresh{} // ViewType == ViewNone
v := views.NewRefresh(r.ViewType, view)
// after
r := arguments.Refresh{ViewType: arguments.ViewHuman}
v := views.NewRefresh(r.ViewType, view) Defensive patterns
Strategy: type-guard
Validate before calling
switch vt {
case arguments.ViewHuman, arguments.ViewJSON:
// ok
default:
return fmt.Errorf("unsupported refresh view type: %v", vt)
} Type guard
func isValidRefreshViewType(vt arguments.ViewType) bool {
return vt == arguments.ViewHuman || vt == arguments.ViewJSON
} Prevention
- Set ViewType explicitly in arguments.Refresh test fixtures.
- Keep NewRefresh in sync with ViewType enum changes.
- Run refresh_test.go after editing the enum.
When it happens
Trigger: `terraform refresh` (now apply -refresh-only) invoked with a ViewType the refresh constructor does not recognize: zero-value ViewType from test code skipping flag parsing, ViewRaw, or a future enum value.
Common situations: A test builds a Refresh view with the default zero ViewType. A maintainer adds a ViewType and forgets to extend NewRefresh. End users cannot trigger via flags.
Related errors
AI-assisted analysis of hashicorp/terraform@d32a084675 (2026-08-11).
Data as JSON: /api/errors/407738085b0febda.
Report an issue: GitHub.
Appendix: source
Thrown at internal/command/views/refresh.go:41
Diagnostics(diags tfdiags.Diagnostics)
HelpPrompt()
}
// NewRefresh returns an initialized Refresh implementation for the given ViewType.
func NewRefresh(vt arguments.ViewType, view *View) Refresh {
switch vt {
case arguments.ViewJSON:
return &RefreshJSON{
view: NewJSONView(view),
}
case arguments.ViewHuman:
return &RefreshHuman{
view: view,
inAutomation: view.RunningInAutomation(),
countHook: &countHook{},
}
default:
panic(fmt.Sprintf("unknown view type %v", vt))
}
}
// The RefreshHuman implementation renders human-readable text logs, suitable for
// a scrolling terminal.
type RefreshHuman struct {
view *View
inAutomation bool
countHook *countHook
}
var _ Refresh = (*RefreshHuman)(nil)
func (v *RefreshHuman) Outputs(outputValues map[string]*states.OutputValue) {
if len(outputValues) > 0 {
v.view.streams.Print(v.view.colorize.Color("[reset][bold][green]\nOutputs:\n\n"))View on GitHub (pinned to d32a084675)