Bool props above bit 31 are silently dropped on 32-bit platforms (BorderLeft, Inline)
Summary
On 32-bit platforms (GOARCH=386, arm, …), BorderLeft(true) and Inline(true) are silently ignored. Left borders vanish, and the corner-trimming pass in the border renderer then drops the corners of the remaining edges too. The library's own test suite already catches it: TestStyleUnset fails on current main under GOARCH=386.
Repro
package main
import (
"fmt"
lipgloss "charm.land/lipgloss/v2"
)
func main() {
s := lipgloss.NewStyle().
BorderStyle(lipgloss.RoundedBorder()).
BorderTop(true).BorderRight(true).BorderBottom(true).BorderLeft(true).
Padding(0, 1)
fmt.Println("GetBorderLeft:", s.GetBorderLeft())
fmt.Println(s.Render("hello"))
}On amd64/arm64:
GetBorderLeft: true
╭───────╮
│ hello │
╰───────╯On 386 (docker run --platform linux/386 golang:1.25 …):
GetBorderLeft: false
───────╮
hello │
───────╯Cause
type propKey int64 with keys built from 1 << iota puts borderLeftKey at bit 32 and inlineKey at bit 43. But bool prop values are folded into attrs int (style.go), and every set/get goes through an int(k) conversion (get.go, set.go). On a 32-bit platform int(borderLeftKey) truncates to 0, so both the set and the get are no-ops. The prop-presence bitfield (props) is already int64, which is why isSet still answers true while the value reads false.
Bit-by-bit on 32-bit int:
- bits 0–30 (
boldKey…borderRightKey): fine - bit 31 (
borderBottomKey): survives by accident, wrapping into the sign bit - bit 32 (
borderLeftKey) and bit 43 (inlineKey): truncated to zero, silently dropped
Fix
Making attrs an int64 (plus the matching casts in get.go/set.go) fixes it; the full test suite then passes under both amd64 and 386. PR incoming.
Context
Found while building the repost CLI for linux/386 to run it inside a browser-embedded x86 VM — every bubbletea panel lost its left border, which took a while to trace down to the style layer.
Source: charmbracelet/lipgloss