{"record":{"id":"473289746548ed01","repo":"signalapp/Signal-Server","slug":"list-size-is-d-but-expected-to-be-one-of-s","errorCode":null,"errorMessage":"list size is [%d] but expected to be one of %s","messagePattern":"list size is \\[(.+?)\\] but expected to be one of (.+?)","errorType":"validation","errorClass":"FieldValidationException","httpStatus":null,"severity":"error","filePath":"service/src/main/java/org/whispersystems/textsecuregcm/grpc/validators/ExactlySizeFieldValidator.java","lineNumber":56,"sourceCode":"  @Override\n  protected void validateStringValue(\n      final Set<Integer> permittedSizes,\n      final String fieldValue) throws FieldValidationException {\n    if (permittedSizes.contains(fieldValue.length())) {\n      return;\n    }\n    throw new FieldValidationException(\"string length is [%d] but expected to be one of %s\".formatted(fieldValue.length(), permittedSizes));\n  }\n\n  @Override\n  protected void validateRepeatedField(\n      final Set<Integer> permittedSizes,\n      final Descriptors.FieldDescriptor fd,\n      final List<?> repeated) throws FieldValidationException {\n    if (permittedSizes.contains(repeated.size())) {\n      return;\n    }\n    throw new FieldValidationException(\"list size is [%d] but expected to be one of %s\".formatted(repeated.size(), permittedSizes));\n  }\n}\n","sourceCodeStart":38,"sourceCodeEnd":59,"githubUrl":"https://github.com/signalapp/Signal-Server/blob/100ab61c82627582c867d19e1c0561ba2781e927/service/src/main/java/org/whispersystems/textsecuregcm/grpc/validators/ExactlySizeFieldValidator.java#L38-L59","documentation":"ExactlySizeFieldValidator.validateRepeatedField checks that a repeated proto field's element count is one of the permitted sizes. If the list size isn't permitted, it throws FieldValidationException with the actual and allowed sizes.","triggerScenarios":"gRPC requests carrying repeated fields (e.g. a list of device IDs, identifiers, or receipts) where the number of elements doesn't match the allowed counts — e.g. sending 0, 2, or 3 items where exactly 1 is required.","commonSituations":"Client sending an empty repeated field that must contain exactly one element; batching multiple items where the endpoint accepts one at a time; deduplication logic removing items and shrinking the list.","solutions":["Check the allowed sizes from the error message and adjust the list to that length client-side","If an empty list is the problem, ensure at least one element is added before sending","Split batched data into multiple requests sized to permitted counts","Validate list size in client code before building the request"],"exampleFix":"// before\nrequest.addAllIdentifiers(Collections.emptyList());\n// after\nrequest.addIdentifiers(identifier); // exactly 1 element","handlingStrategy":"validation","validationCode":"if (!permittedSizes.contains(items.size())) {\n  throw new IllegalArgumentException(\"expected list size in \" + permittedSizes + \", got \" + items.size());\n}","typeGuard":null,"tryCatchPattern":"try {\n  grpcStub.call(request);\n} catch (StatusRuntimeException e) {\n  if (e.getStatus().getCode() == Code.INVALID_ARGUMENT && e.getStatus().getDescription().contains(\"list size\")) {\n    // split or pad the batch to the permitted size and retry\n  }\n}","preventionTips":["Never send empty repeated fields when the schema requires items","Check batch size limits before building requests","Deduplicate/sanitize lists client-side and verify count afterwards"],"tags":["grpc","validation","repeated-field","size-limit"],"backgroundTag":"value-out-of-range","analyzedSha":"100ab61c82627582c867d19e1c0561ba2781e927","analyzedAt":"2026-09-09T13:29:47.883Z","contentChangedAt":"2026-09-09T13:29:47.883Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}