{"record":{"id":"143e3d267c5852c7","repo":"signalapp/Signal-Server","slug":"enum-field-must-be-specified","errorCode":null,"errorMessage":"enum field must be specified","messagePattern":"enum field must be specified","errorType":"validation","errorClass":"FieldValidationException","httpStatus":null,"severity":"error","filePath":"service/src/main/java/org/whispersystems/textsecuregcm/grpc/validators/EnumSpecifiedFieldValidator.java","lineNumber":27,"sourceCode":"import java.util.Set;\n\npublic class EnumSpecifiedFieldValidator extends FieldValidator<Boolean> {\n\n  public EnumSpecifiedFieldValidator() {\n    super(\"specified\", Set.of(Descriptors.FieldDescriptor.Type.ENUM), MissingOptionalAction.FAIL, false);\n  }\n\n  @Override\n  protected Boolean resolveExtensionValue(final Object extensionValue) throws FieldValidationException {\n    return requireFlagExtension(extensionValue);\n  }\n\n  @Override\n  protected void validateEnumValue(\n      final Boolean extensionValue,\n      final Descriptors.EnumValueDescriptor enumValueDescriptor) throws FieldValidationException {\n    if (enumValueDescriptor.getIndex() <= 0) {\n      throw new FieldValidationException(\"enum field must be specified\");\n    }\n  }\n}\n","sourceCodeStart":9,"sourceCodeEnd":31,"githubUrl":"https://github.com/signalapp/Signal-Server/blob/100ab61c82627582c867d19e1c0561ba2781e927/service/src/main/java/org/whispersystems/textsecuregcm/grpc/validators/EnumSpecifiedFieldValidator.java#L9-L31","documentation":"EnumSpecifiedFieldValidator requires proto enum fields to be explicitly set to a non-zero value. Proto3 uses index 0 as the default/unknown value, so if the enum descriptor index is <= 0 the field was left unspecified and FieldValidationException('enum field must be specified') is thrown.","triggerScenarios":"gRPC requests where a required enum field is left at its default (first) enum value or is unset, e.g. omitting a donation/receipt type enum in the request proto.","commonSituations":"Client code forgetting to set the enum field (proto3 silently defaults to 0); protobuf library versions that map unknown values to the first enum; generated-code handling that skips explicitly setting enum values.","solutions":["Explicitly set the enum field to a meaningful (non-first) value in the request builder before sending","Check the generated code so you are not reading/writing the wrong enum field name","If the value is genuinely 'unspecified', use an endpoint or proto that makes the field optional instead"],"exampleFix":"// before\nDonationReceiptData.newBuilder().setAmount(amount).build();\n// after\nDonationReceiptData.newBuilder().setAmount(amount).setPaymentDetailType(PaymentDetailType.PAYPAL).build();","handlingStrategy":"validation","validationCode":"if (request.getPaymentDetailType() == PaymentDetailType.UNRECOGNIZED || request.getPaymentDetailTypeValue() == 0) {\n  throw new IllegalStateException(\"enum field must be set to a non-default value before sending\");\n}","typeGuard":"static <E extends Enum<E>> boolean isSet(E value) { return value != null && value.ordinal() != 0; }","tryCatchPattern":"try {\n  grpcStub.call(request);\n} catch (StatusRuntimeException e) {\n  if (e.getStatus().getCode() == Code.INVALID_ARGUMENT && e.getStatus().getDescription().contains(\"must be specified\")) {\n    // prompt user for the missing enum value\n  }\n}","preventionTips":["Always explicitly set enum fields in proto builders; proto3 defaults them silently to 0","Make required enums first value something obviously invalid (e.g. UNSPECIFIED)","Add client-side pre-send checks for enums the server requires"],"tags":["grpc","enum","proto","validation"],"backgroundTag":"missing-required-argument","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"}