{"record":{"id":"c0f960af563fce5f","repo":"apache/beam","slug":"monogdbio-calculatebucketcount-bundle-size-must-be-greater","errorCode":null,"errorMessage":"monogdbio.calculateBucketCount: bundle size must be greater than 0","messagePattern":"monogdbio\\.calculateBucketCount: bundle size must be greater than 0","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"sdks/go/pkg/beam/io/mongodbio/id_range_split.go","lineNumber":72,"sourceCode":"}\n\nfunc getCollectionSize(ctx context.Context, collection *mongo.Collection) (int64, error) {\n\tcmd := bson.M{\"collStats\": collection.Name()}\n\topts := options.RunCmd().SetReadPreference(readpref.Primary())\n\n\tvar stats struct {\n\t\tSize int64 `bson:\"size\"`\n\t}\n\tif err := collection.Database().RunCommand(ctx, cmd, opts).Decode(&stats); err != nil {\n\t\treturn 0, fmt.Errorf(\"error executing collStats command: %w\", err)\n\t}\n\n\treturn stats.Size, nil\n}\n\nfunc calculateBucketCount(totalSize int64, bundleSize int64) int32 {\n\tif bundleSize < 0 {\n\t\tpanic(\"monogdbio.calculateBucketCount: bundle size must be greater than 0\")\n\t}\n\n\tcount := totalSize / bundleSize\n\tif totalSize%bundleSize != 0 {\n\t\tcount++\n\t}\n\n\tif count > int64(maxBucketCount) {\n\t\tcount = maxBucketCount\n\t}\n\n\treturn int32(count)\n}\n\ntype bucket struct {\n\tID minMax `bson:\"_id\"`\n}\n","sourceCodeStart":54,"sourceCodeEnd":90,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/go/pkg/beam/io/mongodbio/id_range_split.go#L54-L90","documentation":"calculateBucketCount computes how many buckets to split a collection into given total collection size and a per-bundle size. A bundleSize of 0 would divide by zero, so the function panics; note the guard actually checks bundleSize < 0, so a 0 also reaches the division and panics with an integer-divide-by-zero. The check enforces a positive bundle size.","triggerScenarios":"Calling mongodbio.Read with a ReadOption whose BundleSize is 0 or negative, e.g. a user-set option or a computed size that ended up zero (uninitialized struct, division result, misread unit like MB vs bytes yielding 0).","commonSituations":"Custom option funcs setting BundleSize from config that is missing (0 default); unit conversion mistakes (e.g. MB value of 0); copying option struct with zero-value field.","solutions":["Always leave BundleSize at its default (defaultReadBundleSize) or set it to a positive value","Guard user option funcs: if size <= 0 { return fmt.Errorf(...) } so Read panics with the clearer invalid-option message","Check the config source producing 0 (missing key, wrong unit)","Prefer clamping: if option.BundleSize <= 0 { option.BundleSize = defaultReadBundleSize }"],"exampleFix":"// before\noption := &mongodbio.ReadOption{} // BundleSize = 0\nread := mongodbio.Read(s, scope, uri, db, col, typ, option)\n// after\noption := &mongodbio.ReadOption{BundleSize: 64 * 1024 * 1024}\nread := mongodbio.Read(s, scope, uri, db, col, typ, option)","handlingStrategy":"validation","validationCode":"if option.BundleSize <= 0 { return fmt.Errorf(\"BundleSize must be > 0\") }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never construct a zero-value ReadOption; always set BundleSize explicitly or use defaults","Validate bundle-size config at startup with unit checks","Add a test covering BundleSize <= 0 paths"],"tags":["go","mongodb","panic","argument-validation"],"backgroundTag":"invalid-argument-value","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}