qax-os/excelize · error

must call the %s function before the SetRow function

Error message

must call the %s function before the SetRow function

What it means

StreamWriter enforces a strict call order: certain configuration functions must be called before the first SetRow, because after the first row is written the sheet's XML state is committed and column-level settings can no longer be applied. The error names the function (e.g. SetColWidth) that was called after SetRow.

Source

Thrown at errors.go:393

	return fmt.Errorf("parameter 'PivotTableRange' parsing error: %s", msg)
}

// newPivotTableShowValuesAsBaseFieldError defined the error message on receiving
// the invalid pivot table "show values as" base field.
func newPivotTableShowValuesAsBaseFieldError(field string) error {
	return fmt.Errorf("base field %s does not exist in shared items", field)
}

// newStreamSetRowError defined the error message on the stream writer
// receiving the non-ascending row number.
func newStreamSetRowError(row int) error {
	return fmt.Errorf("row %d has already been written", row)
}

// newStreamSetRowOrderError defined the error message on calling the SetRow
// function before the order function.
func newStreamSetRowOrderError(name string) error {
	return fmt.Errorf("must call the %s function before the SetRow function", name)
}

// newUnknownFilterTokenError defined the error message on receiving a unknown
// filter operator token.
func newUnknownFilterTokenError(token string) error {
	return fmt.Errorf("unknown operator: %s", token)
}

// newUnsupportedChartType defined the error message on receiving the chart
// type are unsupported.
func newUnsupportedChartType(chartType ChartType) error {
	return fmt.Errorf("unsupported chart type %d", chartType)
}

// newUnsupportedPivotCacheSourceType defined the error message on receiving the
// source type of pivot table cache.
func newUnsupportedPivotCacheSourceType(sourceType string) error {
	return fmt.Errorf("unsupported pivot table cache source type: %s", sourceType)

View on GitHub (pinned to f2483381fb)

Solutions

  1. Move all SetColWidth/SetColStyle/SetColVisible/SetColOutlineLevel/SetPanes calls above the first SetRow call.
  2. Add a code comment or assertion that no SetRow happens before column configuration is complete.
  3. If column settings depend on data, compute them first, then write rows in a second pass.
  4. For post-hoc column formatting on an already-written sheet, write with StreamWriter then reopen with the regular File API and use SetColWidth/SetColStyle there before saving.

Example fix

// before
sw.SetRow("Sheet1", 0, headerRow)
sw.SetColWidth("Sheet1", 1, 2, 20)
// after
sw.SetColWidth("Sheet1", 1, 2, 20)
sw.SetRow("Sheet1", 0, headerRow)
Defensive patterns

Strategy: validation

Validate before calling

configured := false
func setupStream(sw *excelize.StreamWriter) error {
    if err := sw.SetColWidth(sheet, 1, 10, 18); err != nil {
        return err
    }
    if err := sw.SetPanes(sheet, &excelize.Panes{...}); err != nil {
        return err
    }
    configured = true
    return nil
}

Try / catch

if err := sw.SetColWidth(sheet, 1, 2, 20); err != nil {
    if strings.Contains(err.Error(), "before the SetRow function") {
        return fmt.Errorf("stream column setup must run before SetRow; check call order")
    }
    return err
}

Prevention

When it happens

Trigger: Calling sw.SetColWidth, sw.SetColVisible, sw.SetColStyle, sw.SetColOutlineLevel, or sw.SetPanes on a StreamWriter after sw.SetRow has already written at least one row on that sheet.

Common situations: Configuring column widths at the end of a data-export loop; applying panes/column styles inside the row-writing function; refactoring code that moved SetRow earlier in the flow.

Related errors


AI-assisted analysis of qax-os/excelize@f2483381fb (2026-09-02). Data as JSON: /api/errors/a07a51f06351437b. Report an issue: GitHub.