{"record":{"id":"f7c3344871a3d292","repo":"getsops/sops","slug":"parts-cannot-be-less-than-threshold","errorCode":null,"errorMessage":"parts cannot be less than threshold","messagePattern":"parts cannot be less than threshold","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"shamir/shamir.go","lineNumber":197,"sourceCode":"\treturn accumulator\n}\n\n// add combines two numbers in GF(2^8)\n// This can also be used for subtraction since it is symmetric.\nfunc add(a, b uint8) uint8 {\n\t// Addition in GF(2^8) equals XOR:\n\treturn a ^ b\n}\n\n// Split takes an arbitrarily long secret and generates a `parts`\n// number of shares, `threshold` of which are required to reconstruct\n// the secret. The parts and threshold must be at least 2, and less\n// than 256. The returned shares are each one byte longer than the secret\n// as they attach a tag used to reconstruct the secret.\nfunc Split(secret []byte, parts, threshold int) ([][]byte, error) {\n\t// Sanity check the input\n\tif parts < threshold {\n\t\treturn nil, fmt.Errorf(\"parts cannot be less than threshold\")\n\t}\n\tif parts > 255 {\n\t\treturn nil, fmt.Errorf(\"parts cannot exceed 255\")\n\t}\n\tif threshold < 2 {\n\t\treturn nil, fmt.Errorf(\"threshold must be at least 2\")\n\t}\n\tif threshold > 255 {\n\t\treturn nil, fmt.Errorf(\"threshold cannot exceed 255\")\n\t}\n\tif len(secret) == 0 {\n\t\treturn nil, fmt.Errorf(\"cannot split an empty secret\")\n\t}\n\n\t// Allocate the output array, initialize the final byte\n\t// of the output with the offset. The representation of each\n\t// output is {y1, y2, .., yN, x}.\n\tout := make([][]byte, parts)","sourceCodeStart":179,"sourceCodeEnd":215,"githubUrl":"https://github.com/getsops/sops/blob/13442bb98183887d7a9ac09ec8ab0564673a59d8/shamir/shamir.go#L179-L215","documentation":"Split() requires the total number of parts to be greater than or equal to the threshold; a threshold above the part count is mathematically impossible to satisfy. The library validates this up front and rejects the call.","triggerScenarios":"Calling Split(secret, parts, threshold) with parts < threshold, e.g. Split(secret, 3, 5).","commonSituations":"Swapping the arguments by mistake, computing threshold from configuration while parts comes from a smaller replica count, or copy-pasted unit-test values.","solutions":["Pass parts >= threshold (typically parts == threshold).","Swap the arguments if they were reversed.","Clamp or validate inputs at the call site before invoking Split."],"exampleFix":"// before\nshares, err := shamir.Split(secret, 3, 5)\n// after\nshares, err := shamir.Split(secret, 5, 5)","handlingStrategy":"validation","validationCode":"if parts < threshold {\n    return fmt.Errorf(\"parts (%d) must be >= threshold (%d)\", parts, threshold)\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always pass parts >= threshold (usually equal)","Check argument order when wrapping Split","Validate quorum config at startup"],"tags":["shamir","validation","argument-error","go"],"backgroundTag":"shamir-split-invalid-args","analyzedSha":"13442bb98183887d7a9ac09ec8ab0564673a59d8","analyzedAt":"2026-09-01T03:53:00.447Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}