OpenAPITools/openapi-generator · error · IllegalArgumentException

{} must be one of [NON_NULL, NON_EMPTY, NON_DEFAULT, NONE] b

Error message

{} must be one of [NON_NULL, NON_EMPTY, NON_DEFAULT, NONE] but was: {}

What it means

JsonAnnotationPolicyUtils.normalizeJsonIncludePolicy validates the spring/kotlin-spring option 'optionalNonNullPropertyJsonInclude', which sets the @JsonInclude policy emitted for optional, non-nullable model properties. Unlike the per-property extension, this option accepts only a subset: NON_NULL, NON_EMPTY, NON_DEFAULT, or NONE (no annotation). Other JsonInclude constants (ALWAYS, NON_ABSENT, USE_DEFAULTS, CUSTOM) and any unrecognized string throw IllegalArgumentException.

Source

Thrown at modules/openapi-generator/src/main/java/org/openapitools/codegen/utils/JsonAnnotationPolicyUtils.java:116

     * @param policy      the raw config option value (may be {@code null}, in which case the default
     *                    {@code NON_NULL} is returned)
     * @param optionName  the config option name, used in the error message (kept generator-agnostic)
     * @return the normalized (upper-case) policy name: one of {@code NON_NULL}, {@code NON_EMPTY},
     * {@code NON_DEFAULT}, {@code NONE}.
     * @throws IllegalArgumentException when the value is not one of the supported policies.
     */
    public static String normalizeJsonIncludePolicy(String policy, String optionName) {
        if (policy == null) {
            return JsonIncludePolicy.NON_NULL.name();
        }
        JsonIncludePolicy parsed;
        try {
            parsed = JsonIncludePolicy.valueOf(policy.trim().toUpperCase(java.util.Locale.ROOT));
        } catch (IllegalArgumentException e) {
            parsed = null;
        }
        if (parsed == null || !parsed.isValidOptionalNonNullPolicy()) {
            throw new IllegalArgumentException(optionName
                    + " must be one of " + JsonIncludePolicy.OPTIONAL_NON_NULL_POLICIES + " but was: " + policy);
        }
        return parsed.name();
    }

    /**
     * Read back the {@code optionalNonNullPropertyJsonInclude} config option from {@code additionalProperties},
     * validating/normalizing it via {@link #normalizeJsonIncludePolicy}. Returns {@code current} unchanged when
     * the option was not present in {@code additionalProperties} (i.e. the generator's existing/default value is
     * kept). Callers are responsible for writing the resolved value back via their own
     * {@code writePropertyBack}/{@code additionalProperties.put} convention.
     *
     * @param additionalProperties the generator's additional properties map
     * @param current               the generator's current {@code optionalNonNullPropertyJsonInclude} value
     * @return the resolved {@link JsonIncludePolicy} to assign to the generator's field
     */
    public static JsonIncludePolicy resolveOptionalNonNullPropertyJsonInclude(Map<String, Object> additionalProperties, JsonIncludePolicy current) {
        if (!additionalProperties.containsKey(CodegenConstants.OPTIONAL_NON_NULL_PROPERTY_JSON_INCLUDE)) {

View on GitHub (pinned to fcec517be3)

Solutions

  1. Pick one of NON_NULL (the default), NON_EMPTY, NON_DEFAULT, or NONE.
  2. If you need ALWAYS/NON_ABSENT/USE_DEFAULTS/CUSTOM semantics for specific properties, set x-jackson-json-include-policy per property in the spec instead of this global option.
  3. Re-run; the message echoes the offending value — fix exactly that key in your -D args or config file.

Example fix

# before
openapi-generator-cli generate -g spring \
  -DoptionalNonNullPropertyJsonInclude=ALWAYS

# after
openapi-generator-cli generate -g spring \
  -DoptionalNonNullPropertyJsonInclude=NON_NULL
Defensive patterns

Strategy: validation

Validate before calling

case "$(printf '%s' "$OPT_NONNULL_JSON_INCLUDE" | tr '[:lower:]' '[:upper:]' | tr -d ' ')" in
  NON_NULL|NON_EMPTY|NON_DEFAULT|NONE|"") ;;
  *) echo "ERROR: optionalNonNullPropertyJsonInclude must be NON_NULL, NON_EMPTY, NON_DEFAULT or NONE" >&2; exit 1;;
esac

Type guard

const OPTIONAL_NON_NULL_POLICIES = ['NON_NULL','NON_EMPTY','NON_DEFAULT','NONE'] as const;
type OptionalNonNullPolicy = typeof OPTIONAL_NON_NULL_POLICIES[number];
const isOptionalNonNullPolicy = (v: string): v is OptionalNonNullPolicy =>
  (OPTIONAL_NON_NULL_POLICIES as readonly string[]).includes(v.trim().toUpperCase());

Prevention

When it happens

Trigger: Generating with -g spring -DoptionalNonNullPropertyJsonInclude=ALWAYS, =USE_DEFAULTS, or a typo like =NON-NULL. The value is trimmed and upper-cased before matching, so casing is forgiving but the token must be one of the four allowed names.

Common situations: Assuming every JsonInclude.Include value is accepted because the sibling extension supports them; migrating Jackson global defaults (spring.jackson.default-property-inclusion) verbatim into this generator option; values copied from documentation of a different generator version.

Related errors


AI-assisted analysis of OpenAPITools/openapi-generator@fcec517be3 (2026-08-22). Data as JSON: /api/errors/602e91b4a2d19fbc. Report an issue: GitHub.