{"record":{"id":"ea832e8776b05447","repo":"apache/beam","slug":"panic-err","errorCode":null,"errorMessage":"panic(err)","messagePattern":"panic\\(err\\)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"sdks/go/pkg/beam/io/spannerio/write.go","lineNumber":78,"sourceCode":"\tbeam.ParDo0(s, newWriteFn(db, table, col.Type().Type(), options...), col)\n}\n\ntype writeFn struct {\n\tspannerFn\n\tTable     string           `json:\"table\"`   // The table to write to\n\tType      beam.EncodedType `json:\"type\"`    // Type is the encoded schema type.\n\tOptions   writeOptions     `json:\"options\"` // Spanner write options\n\tmutations []*spanner.Mutation\n}\n\nfunc newWriteFn(db string, table string, t reflect.Type, options ...WriteOptionsFn) *writeFn {\n\twriteOptions := writeOptions{\n\t\tBatchSize: 1000, // default\n\t}\n\n\tfor _, opt := range options {\n\t\tif err := opt(&writeOptions); err != nil {\n\t\t\tpanic(err)\n\t\t}\n\t}\n\n\treturn &writeFn{spannerFn: newSpannerFn(db), Table: table, Type: beam.EncodedType{T: t}, Options: writeOptions}\n}\n\nfunc (f *writeFn) Setup(ctx context.Context) error {\n\treturn f.spannerFn.Setup(ctx)\n}\n\nfunc (f *writeFn) Teardown() {\n\tf.spannerFn.Teardown()\n}\n\nfunc (f *writeFn) ProcessElement(ctx context.Context, value beam.X) error {\n\tmutation, err := spanner.InsertOrUpdateStruct(f.Table, value)\n\tif err != nil {\n\t\treturn err","sourceCodeStart":60,"sourceCodeEnd":96,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/go/pkg/beam/io/spannerio/write.go#L60-L96","documentation":"newWriteFn panics when any WriteOptionsFn option function returns a non-nil error while building the write DoFn. Option constructors validate their inputs (e.g. batch size bounds) and surface failures here.","triggerScenarios":"Calling spannerio.Write with an invalid option value, e.g. a WriteOptionsFn constructed with a non-positive batch size.","commonSituations":"Batch size derived from config that can be 0 or negative, typos in option values, or hand-written option functions that return errors on unexpected inputs.","solutions":["Fix the option values passed to Write, e.g. ensure the batch size is a positive integer.","Validate option parameters at config-load time before building the pipeline.","If using custom WriteOptionsFn implementations, return errors deliberately only for truly invalid input and fix the caller."],"exampleFix":"// before\nspannerio.Write(s, db, \"users\", col, spannerio.WriteBatchSize(cfg.BatchSize)) // 0\n// after\nif cfg.BatchSize <= 0 {\n    cfg.BatchSize = 1000\n}\nspannerio.Write(s, db, \"users\", col, spannerio.WriteBatchSize(cfg.BatchSize))","handlingStrategy":"validation","validationCode":"if batchSize <= 0 {\n    return fmt.Errorf(\"write batch size must be positive, got %d\", batchSize)\n}","typeGuard":null,"tryCatchPattern":"defer func() {\n    if r := recover(); r != nil {\n        err = fmt.Errorf(\"invalid spanner write option: %v\", r)\n    }\n}()","preventionTips":["Validate all option inputs (batch size, etc.) where they are read from config, before calling Write.","Prefer explicit constants over config-derived option values when values have invariants.","Wrap pipeline construction in a recover helper that reports option errors clearly."],"tags":["go","apache-beam","spanner","options"],"backgroundTag":"invalid-config-value","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-20T03:17:13.778Z"}