{"record":{"id":"a07a51f06351437b","repo":"qax-os/excelize","slug":"must-call-the-s-function-before-the-setrow-functi","errorCode":null,"errorMessage":"must call the %s function before the SetRow function","messagePattern":"must call the (.+?) function before the SetRow function","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"errors.go","lineNumber":393,"sourceCode":"\treturn fmt.Errorf(\"parameter 'PivotTableRange' parsing error: %s\", msg)\n}\n\n// newPivotTableShowValuesAsBaseFieldError defined the error message on receiving\n// the invalid pivot table \"show values as\" base field.\nfunc newPivotTableShowValuesAsBaseFieldError(field string) error {\n\treturn fmt.Errorf(\"base field %s does not exist in shared items\", field)\n}\n\n// newStreamSetRowError defined the error message on the stream writer\n// receiving the non-ascending row number.\nfunc newStreamSetRowError(row int) error {\n\treturn fmt.Errorf(\"row %d has already been written\", row)\n}\n\n// newStreamSetRowOrderError defined the error message on calling the SetRow\n// function before the order function.\nfunc newStreamSetRowOrderError(name string) error {\n\treturn fmt.Errorf(\"must call the %s function before the SetRow function\", name)\n}\n\n// newUnknownFilterTokenError defined the error message on receiving a unknown\n// filter operator token.\nfunc newUnknownFilterTokenError(token string) error {\n\treturn fmt.Errorf(\"unknown operator: %s\", token)\n}\n\n// newUnsupportedChartType defined the error message on receiving the chart\n// type are unsupported.\nfunc newUnsupportedChartType(chartType ChartType) error {\n\treturn fmt.Errorf(\"unsupported chart type %d\", chartType)\n}\n\n// newUnsupportedPivotCacheSourceType defined the error message on receiving the\n// source type of pivot table cache.\nfunc newUnsupportedPivotCacheSourceType(sourceType string) error {\n\treturn fmt.Errorf(\"unsupported pivot table cache source type: %s\", sourceType)","sourceCodeStart":375,"sourceCodeEnd":411,"githubUrl":"https://github.com/qax-os/excelize/blob/f2483381fbfbe432a6baa98d48a1c277183f3285/errors.go#L375-L411","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Move all SetColWidth/SetColStyle/SetColVisible/SetColOutlineLevel/SetPanes calls above the first SetRow call.","Add a code comment or assertion that no SetRow happens before column configuration is complete.","If column settings depend on data, compute them first, then write rows in a second pass.","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."],"exampleFix":"// before\nsw.SetRow(\"Sheet1\", 0, headerRow)\nsw.SetColWidth(\"Sheet1\", 1, 2, 20)\n// after\nsw.SetColWidth(\"Sheet1\", 1, 2, 20)\nsw.SetRow(\"Sheet1\", 0, headerRow)","handlingStrategy":"validation","validationCode":"configured := false\nfunc setupStream(sw *excelize.StreamWriter) error {\n    if err := sw.SetColWidth(sheet, 1, 10, 18); err != nil {\n        return err\n    }\n    if err := sw.SetPanes(sheet, &excelize.Panes{...}); err != nil {\n        return err\n    }\n    configured = true\n    return nil\n}","typeGuard":null,"tryCatchPattern":"if err := sw.SetColWidth(sheet, 1, 2, 20); err != nil {\n    if strings.Contains(err.Error(), \"before the SetRow function\") {\n        return fmt.Errorf(\"stream column setup must run before SetRow; check call order\")\n    }\n    return err\n}","preventionTips":["Adopt a fixed StreamWriter recipe: SetCol*/SetPanes first, then rows","Never configure columns inside the row-writing loop","Wrap stream setup in one function called before any SetRow","Review diffs that move SetRow calls earlier in the flow"],"tags":["go","excelize","streamwriter","call-order"],"backgroundTag":"api-call-order-violation","analyzedSha":"f2483381fbfbe432a6baa98d48a1c277183f3285","analyzedAt":"2026-09-02T01:26:19.299Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T06:17:21.866Z"}