{"record":{"id":"8331467b7b7b12c0","repo":"apache/beam","slug":"n-must-be-0-top","errorCode":null,"errorMessage":"n must be > 0","messagePattern":"n must be > 0","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"sdks/go/pkg/beam/transforms/top/top.go","lineNumber":103,"sourceCode":"\n\treturn beam.Combine(s, newCombineFn(less, n, t.Type(), true), col)\n}\n\n// SmallestPerKey returns the smallest N values for each key of a PCollection<KV<K,T>>.\n// The order is defined by the comparator, less : T x T -> bool. It returns a\n// PCollection<KV<K,[]T>> with a slice of the N smallest elements for each key.\nfunc SmallestPerKey(s beam.Scope, col beam.PCollection, n int, less any) beam.PCollection {\n\ts = s.Scope(fmt.Sprintf(\"top.SmallestPerKey(%v)\", n))\n\n\t_, t := beam.ValidateKVType(col)\n\tvalidate(t, n, less)\n\n\treturn beam.CombinePerKey(s, newCombineFn(less, n, t.Type(), true), col)\n}\n\nfunc validate(t typex.FullType, n int, less any) {\n\tif n < 1 {\n\t\tpanic(\"n must be > 0\")\n\t}\n\tfuncx.MustSatisfy(less, funcx.Replace(sig, beam.TType, t.Type()))\n}\n\nfunc newCombineFn(less any, n int, t reflect.Type, reversed bool) *combineFn {\n\tfn := &combineFn{Less: beam.EncodedFunc{Fn: reflectx.MakeFunc(less)}, N: n, Type: beam.EncodedType{T: t}, Reversed: reversed}\n\t// Running SetupFn at pipeline construction helps validate the\n\t// combineFn, and simplify testing.\n\tfn.Setup()\n\treturn fn\n}\n\n// TODO(herohde) 5/25/2017: use a heap instead of a sorted slice.\n\ntype accum struct {\n\tenc beam.ElementEncoder\n\tdec beam.ElementDecoder\n","sourceCodeStart":85,"sourceCodeEnd":121,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/go/pkg/beam/transforms/top/top.go#L85-L121","documentation":"top.Smallest, top.Largest and their PerKey variants call validate, which panics if n (the number of top elements to keep) is less than 1. n must be a positive integer; the transform cannot produce 'top 0' results.","triggerScenarios":"Calling top.Largest(s, col, n, less) or top.Smallest / LargestPerKey / SmallestPerKey with n = 0 or a negative n, e.g. when n comes from an unset config variable defaulting to 0.","commonSituations":"A limit/topN config field left at its zero value; computing n from user input or a query parameter without validation; an off-by-one where a caller passes a count minus one.","solutions":["Validate n >= 1 at your pipeline's configuration boundary before constructing the transform.","Default an unset topN config to a sensible positive value (e.g. 10).","Clamp with a helper like max(1, n) if zero should mean 'no limit' in your domain."],"exampleFix":"// before\nn := cfg.TopN // 0 when unset\ntop.Largest(s, col, n, less) // panics\n\n// after\nn := cfg.TopN\nif n < 1 {\n    n = 10\n}\ntop.Largest(s, col, n, less)","handlingStrategy":"validation","validationCode":"if n < 1 {\n    return fmt.Errorf(\"top.*: n must be >= 1, got %d\", n)\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Validate all numeric pipeline options at config-load time.","Give topN-style settings positive defaults.","Never pass raw user input counts straight into transforms without clamping."],"tags":["go","apache-beam","panic","argument-validation","top"],"backgroundTag":"argument-out-of-range","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"}