The interactive TUI mode (--interactive) was experiencing a panic immediately after connecting to vSphere and loading VMs.
Error message:
ERROR: application failed | error=TUI error: program was killed: program experienced a panic
Location: cmd/hyperexport/main.go:1984-2024 (tuiModel initialization)
Issue: The spinner field in tuiModel struct was not being initialized, but the Init() method was calling m.spinner.Tick at interactive_tui.go:787.
Fix: Added spinner initialization in runInteractiveTUI():
// Initialize spinner
s := spinner.New()
s.Spinner = spinner.Dot
s.Style = lipgloss.NewStyle().Foreground(lipgloss.Color("205"))
And added import: "github.com/charmbracelet/bubbles/spinner"
Location: cmd/hyperexport/main.go:1984-2024 (tuiModel initialization)
Issue: The searchInput field (textinput.Model) was not initialized. Would have caused a panic when user pressed “/” to search (at interactive_tui.go:1054).
Fix: Added textinput initialization:
// Initialize search input
si := textinput.New()
si.Placeholder = "Type to search VMs..."
si.CharLimit = 100
And added import: "github.com/charmbracelet/bubbles/textinput"
Location: cmd/hyperexport/interactive_tui.go:944-955
Issue: In the tickMsg handler, the code was incorrectly passing a tickMsg (type time.Time) to m.spinner.Update(msg), but the spinner only accepts spinner.TickMsg. This type mismatch caused a panic.
Original buggy code:
case tickMsg:
m.animFrame++
var cmd tea.Cmd
if m.phase == "export" || m.phase == "validation" || m.phase == "cloudupload" {
cmd = tickCmd()
}
// BUG: passing wrong message type to spinner
m.spinner, cmd = m.spinner.Update(msg)
return m, cmd
Fixed code:
case tickMsg:
m.animFrame++
if m.phase == "export" || m.phase == "validation" || m.phase == "cloudupload" {
return m, tickCmd()
}
return m, nil
Explanation: The spinner has its own separate tick message handling via spinner.TickMsg (lines 957-960). The custom tickMsg handler should only manage animation frames and phase-specific ticking, not update the spinner.
cmd/hyperexport/main.go
cmd/hyperexport/interactive_tui.go
build/hyperexport --interactivetickMsg: Custom message for animation frames (every 100ms)spinner.TickMsg: Bubbletea spinner’s own tick messageprogress.Model: Progress bar (already initialized)help.Model: Help display (already initialized)spinner.Model: Loading spinner (NOW initialized)textinput.Model: Search input (NOW initialized)✅ All critical initialization issues resolved ✅ Message type handling corrected ✅ Build successful ✅ Ready for testing