{"record":{"id":"68fd0ac3ee32238f","repo":"theonedev/onedev","slug":"invalid-choice-value","errorCode":null,"errorMessage":"Invalid choice value","messagePattern":"Invalid choice value","errorType":"validation","errorClass":"ValidationException","httpStatus":null,"severity":"error","filePath":"server-core/src/main/java/io/onedev/server/buildspecmodel/inputspec/choiceinput/ChoiceInput.java","lineNumber":70,"sourceCode":"\t\t\tList<String> possibleValues = inputSpec.getPossibleValues();\n\t\t\tif (!possibleValues.isEmpty()) {\n\t\t\t\tList<String> copyOfStrings = new ArrayList<>(strings);\n\t\t\t\tcopyOfStrings.removeAll(possibleValues);\n\t\t\t\tif (!copyOfStrings.isEmpty())\n\t\t\t\t\tthrow new ValidationException(\"Invalid choice values: \" + copyOfStrings);\n\t\t\t\telse\n\t\t\t\t\treturn strings;\n\t\t\t} else {\n\t\t\t\treturn strings;\n\t\t\t}\n\t\t} else if (strings.size() == 0) {\n\t\t\treturn null;\n\t\t} else if (strings.size() == 1) {\n\t\t\tString value = strings.iterator().next();\n\t\t\tList<String> possibleValues = inputSpec.getPossibleValues();\n\t\t\tif (!possibleValues.isEmpty()) {\n\t\t\t\tif (!possibleValues.contains(value))\n\t\t\t\t\tthrow new ValidationException(\"Invalid choice value\");\n\t\t\t\telse\n\t\t\t\t\treturn value;\n\t\t\t} else {\n\t\t\t\treturn value;\n\t\t\t}\n\t\t} else {\n\t\t\tthrow new ValidationException(\"Not eligible for multi-value\");\n\t\t}\n\t}\n\n\t@SuppressWarnings(\"unchecked\")\n\tpublic static List<String> convertToStrings(InputSpec inputSpec, Object value) {\n\t\tList<String> strings = new ArrayList<>();\n\t\tif (inputSpec.isAllowMultiple()) {\n\t\t\tif (inputSpec.checkListElements(value, String.class))\n\t\t\t\tstrings.addAll((List<String>) value);\n\t\t\tCollections.sort(strings);\n\t\t} else if (value instanceof String) {","sourceCodeStart":52,"sourceCodeEnd":88,"githubUrl":"https://github.com/theonedev/onedev/blob/d44925c47c37992c828ea673a5f9620539bc3ff2/server-core/src/main/java/io/onedev/server/buildspecmodel/inputspec/choiceinput/ChoiceInput.java#L52-L88","documentation":"ChoiceInput.convertToObject validates a single-choice input value. When the input is not multi-value and exactly one string is submitted, the value must exist in the input's possibleValues list; otherwise a ValidationException is thrown. The message does not echo the offending value, so consult the spec to find what is allowed.","triggerScenarios":"Calling ChoiceInput.convertToObject on a ChoiceInput with isAllowMultiple()==false, exactly one submitted string, and a non-empty possibleValues list that does not contain that string (possibleValues.contains(value) is false).","commonSituations":"Typo or case mismatch in a job parameter value; the choice list was renamed in the build spec while old values persist in saved job pipelines or schedules; copy-pasting a value from a different input.","solutions":["Compare the submitted value against the input's possibleValues and fix the spelling/case to match exactly.","Update stale job parameters or schedules still referencing a renamed choice value.","Add the value to possibleValues if it is a legitimate new option.","If free-form values are desired, clear possibleValues (empty list bypasses the check)."],"exampleFix":"// before\nvalue: \"Prod\"    // possibleValues: [prod, staging]\n// after\nvalue: \"prod\"","handlingStrategy":"validation","validationCode":"if (values.size() == 1 && !inputSpec.getPossibleValues().isEmpty()\n    && !inputSpec.getPossibleValues().contains(values.iterator().next()))\n    throw new IllegalArgumentException(\"Value not in choice list: \" + values.iterator().next());","typeGuard":"boolean isAllowedChoice(String value, ChoiceInput spec) {\n    return spec.getPossibleValues().isEmpty() || spec.getPossibleValues().contains(value);\n}","tryCatchPattern":"try {\n    Object result = ChoiceInput.convertToObject(inputSpec, strings);\n} catch (ValidationException e) {\n    logger.warn(\"Value {} is not one of {}\", strings, inputSpec.getPossibleValues());\n    // prompt user to re-pick or use a default\n}","preventionTips":["Populate choice inputs from a dropdown fed by possibleValues rather than free text.","Use the ChoiceInput's own UI component so only valid values can be submitted.","Migrate persisted parameters whenever possibleValues change.","Check case-sensitivity when copying values."],"tags":["validation","buildspec","choice-input"],"backgroundTag":"invalid-enum-value","analyzedSha":"d44925c47c37992c828ea673a5f9620539bc3ff2","analyzedAt":"2026-09-06T07:18:27.995Z","contentChangedAt":"2026-09-06T07:18:27.995Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}