Skip to content

fix: prevent footer panic on narrow widths and long titles - #47

Open
jonasws wants to merge 1 commit into
plutov:mainfrom
jonasws:fix/footer-negative-repeat-panic
Open

jonasws wants to merge 1 commit into
plutov:mainfrom
jonasws:fix/footer-negative-repeat-panic

Conversation

@jonasws

@jonasws jonasws commented Jun 25, 2026

Copy link
Copy Markdown

Fix footer panic on narrow widths and long titles

Summary

renderFooter crashes the whole TUI with strings: negative Repeat count for some specs / terminal sizes.

The bug

renderFooter builds the footer padding like this:

strings.Repeat(" ", m.width-len(helpText)-len(schemaInfo)-2)

schemaInfo is "<info.title> v<info.version>". When that string is long relative to the terminal width — a long API title, or just a narrow window — the count goes negative, and strings.Repeat panics on a negative count:

Caught panic:

strings: negative Repeat count

...
strings.Repeat(...)
main.Model.renderFooter(...)  view.go:359
main.Model.View(...)          model.go:400

The guard above only zeroes helpText; it never accounts for schemaInfo itself overflowing, so even an empty helpText can't save it.

A second, latent issue: widths are measured with len() (bytes), not display columns. A multi-byte info.title over-counts versus the real terminal width and can drive the count negative even when the text visually fits. renderHeader already uses lipgloss.Width() for this; the footer was inconsistent.

The fix

  • Clamp the padding count at 0 before strings.Repeat.
  • Measure widths with lipgloss.Width() instead of len(), matching renderHeader and correctly handling Unicode titles.

The sibling renderers (renderEndpoints / renderComponents / renderWebhooks) get their repeat count from calculateContentWidth, which already clamps via max(1, ...), so they were never affected and are left unchanged.

Testing

Added TestFooterRenderNarrowWidth, which drives renderFooter and View() at widths 0, 1, 10, and 40 against a spec with a long title + version. It panics before the fix and passes after.

  • go test -v passes
  • Existing 3.0 / 3.1 / 3.2 example specs unaffected
  • No GIF regeneration — the change is footer padding only, no layout/flow change

  renderFooter passed `m.width - len(helpText) - len(schemaInfo) - 2`
  straight to strings.Repeat. When the spec's info.title/version was long
  or the terminal narrow, the count went negative and strings.Repeat
  panicked with "strings: negative Repeat count", crashing the TUI.

  Clamp the padding count at zero. Also measure widths with
  lipgloss.Width instead of len so multi-byte titles are counted by
  display columns, not bytes — matching how renderHeader already
  measures and avoiding a false negative count on Unicode titles.

  Add TestFooterRenderNarrowWidth, which drives renderFooter and View at
  widths 0/1/10/40 with a long title; it panics before the fix and
  passes after.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant