{"record":{"id":"277555ea0b98502f","repo":"charmbracelet/gum","slug":"unable-to-parse-columns","errorCode":null,"errorMessage":"unable to parse columns","messagePattern":"unable to parse columns","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"table/command.go","lineNumber":59,"sourceCode":"\treader.LazyQuotes = o.LazyQuotes\n\treader.FieldsPerRecord = o.FieldsPerRecord\n\tseparatorRunes := []rune(o.Separator)\n\tif len(separatorRunes) != 1 {\n\t\treturn fmt.Errorf(\"separator must be single character\")\n\t}\n\treader.Comma = separatorRunes[0]\n\n\twriter := csv.NewWriter(os.Stdout)\n\twriter.Comma = separatorRunes[0]\n\n\tvar columnNames []string\n\tvar err error\n\t// If no columns are provided we'll use the first row of the CSV as the\n\t// column names.\n\tif len(o.Columns) <= 0 {\n\t\tcolumnNames, err = reader.Read()\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"unable to parse columns\")\n\t\t}\n\t} else {\n\t\tcolumnNames = o.Columns\n\t}\n\n\tdata, err := reader.ReadAll()\n\tif err != nil {\n\t\treturn fmt.Errorf(\"invalid data provided\")\n\t}\n\tcolumns := make([]table.Column, 0, len(columnNames))\n\n\tfor i, title := range columnNames {\n\t\twidth := lipgloss.Width(title)\n\t\tif len(o.Widths) > i {\n\t\t\twidth = o.Widths[i]\n\t\t}\n\t\tcolumns = append(columns, table.Column{\n\t\t\tTitle: title,","sourceCodeStart":41,"sourceCodeEnd":77,"githubUrl":"https://github.com/charmbracelet/gum/blob/4d089f95507708a71f64dacfe7ca513219dd5267/table/command.go#L41-L77","documentation":"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.","triggerScenarios":"`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.","commonSituations":"Empty or whitespace-only files; CSVs with unbalanced quotes; files with a malformed first line; binary/BOM-corrupted input reaching the csv.Reader.","solutions":["Verify the input file/stream is non-empty and starts with a valid CSV header row.","Add --lazy-quotes if the data contains unescaped quotes.","Supply explicit headers with --columns so reader.Read() isn't needed: `gum table --columns a,b`.","Sanitize encoding issues (gum already strips BOM) and remove binary garbage.","Test the row with another tool first (e.g. `head -1 data.csv | csvtool`)."],"exampleFix":"// before (empty input)\n: | gum table\n// after\necho \"name,age\" | gum table\n# or provide columns explicitly\nprintf 'x\\n' | gum table --columns name,age","handlingStrategy":"validation","validationCode":"if [ ! -s data.csv ]; then echo \"empty input\" >&2; exit 1; fi\nhead -1 data.csv | grep -q ',' || echo \"warning: header row may be malformed\" >&2\ngum table --file data.csv","typeGuard":null,"tryCatchPattern":"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","preventionTips":["Ensure input starts with a well-formed header row","Use --lazy-quotes for sloppy CSV quoting","Pass explicit --columns to skip header detection entirely","Validate the CSV with an independent parser first"],"tags":["csv","parsing","input-validation"],"backgroundTag":"csv-parse-failed","analyzedSha":"4d089f95507708a71f64dacfe7ca513219dd5267","analyzedAt":"2026-08-31T18:45:06.436Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}