{"record":{"id":"0e6febbdba2c373f","repo":"hashicorp/terraform","slug":"unknown-view-type-v-0e6feb","errorCode":null,"errorMessage":"unknown view type %v","messagePattern":"unknown view type (.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"internal/command/views/state_locker.go","lineNumber":29,"sourceCode":"\t\"github.com/hashicorp/terraform/internal/command/arguments\"\n)\n\n// The StateLocker view is used to display locking/unlocking status messages\n// if the state lock process takes longer than expected.\ntype StateLocker interface {\n\tLocking()\n\tUnlocking()\n}\n\n// NewStateLocker returns an initialized StateLocker implementation for the given ViewType.\nfunc NewStateLocker(vt arguments.ViewType, view *View) StateLocker {\n\tswitch vt {\n\tcase arguments.ViewHuman:\n\t\treturn &StateLockerHuman{view: view}\n\tcase arguments.ViewJSON:\n\t\treturn &StateLockerJSON{view: view}\n\tdefault:\n\t\tpanic(fmt.Sprintf(\"unknown view type %v\", vt))\n\t}\n}\n\n// StateLockerHuman is an implementation of StateLocker which prints status to\n// a terminal.\ntype StateLockerHuman struct {\n\tview *View\n}\n\nvar _ StateLocker = (*StateLockerHuman)(nil)\nvar _ StateLocker = (*StateLockerJSON)(nil)\n\nfunc (v *StateLockerHuman) Locking() {\n\tv.view.streams.Println(\"Acquiring state lock. This may take a few moments...\")\n}\n\nfunc (v *StateLockerHuman) Unlocking() {\n\tv.view.streams.Println(\"Releasing state lock. This may take a few moments...\")","sourceCodeStart":11,"sourceCodeEnd":47,"githubUrl":"https://github.com/hashicorp/terraform/blob/d32a084675427f5ac3f7d2868578ef8b2c1dc525/internal/command/views/state_locker.go#L11-L47","documentation":"NewStateLocker (internal/command/views/state_locker.go:18) switches over arguments.ViewType and constructs a StateLockerHuman for ViewHuman or StateLockerJSON for ViewJSON; any other rune hits default and panics 'unknown view type %v'. arguments.ViewType is a rune with ViewNone(0), ViewHuman('H'), ViewJSON('J'), ViewRaw('R').","triggerScenarios":"A state-modifying command path invokes NewStateLocker with a ViewType that is neither ViewHuman nor ViewJSON — i.e. ViewNone (uninitialized zero value leaking through), ViewRaw, or a rune introduced without updating this switch.","commonSituations":"A code change that constructs a StateShow/StateMigrate/etc. arguments struct without setting ViewType (leaving ViewNone), a new output mode added to arguments.types.go without a matching StateLocker implementation, or a test/automation harness injecting an unexpected view type.","solutions":["Ensure the command's argument parser always sets ViewType to ViewHuman or ViewJSON before NewStateLocker is reached; default to ViewHuman when no -json flag is present.","If adding a new ViewType, implement the matching StateLocker variant and add its case here in the same change.","Add a unit test that exercises NewStateLocker with every defined ViewType constant to catch missing branches.","If you are a CLI user, this is an internal Terraform bug — report it with the exact subcommand and flags that triggered the panic."],"exampleFix":"// before\ndefault:\n    panic(fmt.Sprintf(\"unknown view type %v\", vt))\n\n// after (return a safe default view instead of crashing)\ndefault:\n    return &StateLockerHuman{view: view}","handlingStrategy":"validation","validationCode":"// Validate the ViewType before constructing a StateLocker.\nfunc validLockerViewType(vt arguments.ViewType) bool {\n    return vt == arguments.ViewHuman || vt == arguments.ViewJSON\n}\n// caller:\nif !validLockerViewType(args.ViewType) {\n    return nil, fmt.Errorf(\"state locker requires ViewHuman or ViewJSON, got %v\", args.ViewType)\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always default ViewType to ViewHuman in argument parsers when no -json flag is set, so an uninitialized struct never reaches NewStateLocker.","When adding a new ViewType, audit every New* constructor switch and add a case (or an explicit rejection) in the same change.","Add table-driven tests covering NewStateLocker for every ViewType constant."],"tags":["panic","view-type","exhaustive-switch","state-locker","internal-bug"],"backgroundTag":null,"analyzedSha":"d32a084675427f5ac3f7d2868578ef8b2c1dc525","analyzedAt":"2026-08-11T18:43:52.779Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}