charmbracelet/gum · error

unable to parse columns

Error message

unable to parse columns

What it means

When no --columns are supplied, gum table reads the first CSV row as header names via reader.Read(). If that fails (empty input, malformed CSV, encoding issues), Run returns 'unable to parse columns'. Note the underlying error is discarded, so the cause must be inferred.

Source

Thrown at table/command.go:59

	reader.LazyQuotes = o.LazyQuotes
	reader.FieldsPerRecord = o.FieldsPerRecord
	separatorRunes := []rune(o.Separator)
	if len(separatorRunes) != 1 {
		return fmt.Errorf("separator must be single character")
	}
	reader.Comma = separatorRunes[0]

	writer := csv.NewWriter(os.Stdout)
	writer.Comma = separatorRunes[0]

	var columnNames []string
	var err error
	// If no columns are provided we'll use the first row of the CSV as the
	// column names.
	if len(o.Columns) <= 0 {
		columnNames, err = reader.Read()
		if err != nil {
			return fmt.Errorf("unable to parse columns")
		}
	} else {
		columnNames = o.Columns
	}

	data, err := reader.ReadAll()
	if err != nil {
		return fmt.Errorf("invalid data provided")
	}
	columns := make([]table.Column, 0, len(columnNames))

	for i, title := range columnNames {
		width := lipgloss.Width(title)
		if len(o.Widths) > i {
			width = o.Widths[i]
		}
		columns = append(columns, table.Column{
			Title: title,

View on GitHub (pinned to 4d089f9550)

Solutions

  1. Verify the input file/stream is non-empty and starts with a valid CSV header row.
  2. Add --lazy-quotes if the data contains unescaped quotes.
  3. Supply explicit headers with --columns so reader.Read() isn't needed: `gum table --columns a,b`.
  4. Sanitize encoding issues (gum already strips BOM) and remove binary garbage.
  5. Test the row with another tool first (e.g. `head -1 data.csv | csvtool`).

Example fix

// before (empty input)
: | gum table
// after
echo "name,age" | gum table
# or provide columns explicitly
printf 'x\n' | gum table --columns name,age
Defensive patterns

Strategy: validation

Validate before calling

if [ ! -s data.csv ]; then echo "empty input" >&2; exit 1; fi
head -1 data.csv | grep -q ',' || echo "warning: header row may be malformed" >&2
gum table --file data.csv

Try / catch

if ! gum table --file data.csv 2>err.log; then gum table --file data.csv --lazy-quotes || echo "unparseable CSV: $(cat err.log)" >&2; fi

Prevention

When it happens

Trigger: `cat empty.csv | gum table` (zero bytes → io.EOF on Read); `printf 'a,b\nc' | gum table` is fine but input that fails csv parsing on row 1, such as lone quote characters without --lazy-quotes, triggers it.

Common situations: Empty or whitespace-only files; CSVs with unbalanced quotes; files with a malformed first line; binary/BOM-corrupted input reaching the csv.Reader.

Understand the failure class

Related errors


AI-assisted analysis of charmbracelet/gum@4d089f9550 (2026-08-31). Data as JSON: /api/errors/277555ea0b98502f. Report an issue: GitHub.