OpenAPITools/openapi-generator · error · IllegalArgumentException
{} must be a valid com.fasterxml.jackson.annotation.JsonIncl
Error message
{} must be a valid com.fasterxml.jackson.annotation.JsonInclude.Include value (ALWAYS, NON_NULL, NON_ABSENT, NON_EMPTY, NON_DEFAULT, USE_DEFAULTS, CUSTOM), or NONE to emit no annotation, but was: {} What it means
JsonAnnotationPolicyUtils.resolveManualJsonIncludePolicy (used by the spring and kotlin-spring generators) validates a per-property 'x-jackson-json-include-policy' vendor extension from the spec. The value must be a Jackson JsonInclude.Include constant — ALWAYS, NON_NULL, NON_ABSENT, NON_EMPTY, NON_DEFAULT, USE_DEFAULTS, CUSTOM — or NONE/blank meaning 'emit no annotation'. Anything else throws IllegalArgumentException, with the extension name prefixed so you know where to look.
Source
Thrown at modules/openapi-generator/src/main/java/org/openapitools/codegen/utils/JsonAnnotationPolicyUtils.java:84
private JsonAnnotationPolicyUtils() {
}
/**
* Validate and normalize a manual per-property {@code x-jackson-json-include-policy} override.
*
* @param rawPolicy the raw vendor extension value set directly on the property in the spec
* @param extensionName the vendor extension key, used in the error message (kept generator-agnostic)
* @return the normalized (upper-case) policy name to emit, or {@code null} when the override means
* "emit no annotation" ({@code NONE}/blank), in which case the caller must drop the extension.
* @throws IllegalArgumentException when the override is not a valid {@code JsonInclude.Include} value.
*/
public static String resolveManualJsonIncludePolicy(Object rawPolicy, String extensionName) {
JsonIncludePolicy parsed;
try {
parsed = JsonIncludePolicy.parse(rawPolicy);
} catch (IllegalArgumentException e) {
throw new IllegalArgumentException(extensionName
+ " must be a valid com.fasterxml.jackson.annotation.JsonInclude.Include value "
+ "(ALWAYS, NON_NULL, NON_ABSENT, NON_EMPTY, NON_DEFAULT, USE_DEFAULTS, CUSTOM), or NONE to emit "
+ "no annotation, but was: " + rawPolicy);
}
if (parsed == null || !parsed.isEmitted()) {
return null;
}
return parsed.name();
}
/**
* Validate and normalize the {@code optionalNonNullPropertyJsonInclude} config option value.
*
* @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}.View on GitHub (pinned to fcec517be3)
Solutions
- Use an exact JsonInclude.Include enum name in the spec: NON_NULL, NON_EMPTY, NON_DEFAULT, ALWAYS, NON_ABSENT, USE_DEFAULTS, CUSTOM (underscores, case-insensitive).
- Use NONE or an empty value when you want no @JsonInclude emitted for that property.
- Search your spec for x-jackson-json-include-policy and validate each occurrence against the enum list in the error message.
Example fix
# before (openapi.yaml)
components:
schemas:
User:
properties:
email:
type: string
x-jackson-json-include-policy: non-null
# after
x-jackson-json-include-policy: NON_NULL Defensive patterns
Strategy: validation
Validate before calling
// Node: validate x-jackson-json-include-policy values in the spec
const ALLOWED = new Set(['ALWAYS','NON_NULL','NON_ABSENT','NON_EMPTY','NON_DEFAULT','USE_DEFAULTS','CUSTOM','NONE','']);
const check = (o) => { for (const [k, v] of Object.entries(o ?? {})) {
if (k === 'x-jackson-json-include-policy' && !ALLOWED.has(String(v).trim().toUpperCase()))
throw new Error(`invalid x-jackson-json-include-policy: ${v}`);
if (v && typeof v === 'object') check(v);
}};
check(require('./openapi.json')); Type guard
const JSON_INCLUDE_POLICIES = ['ALWAYS','NON_NULL','NON_ABSENT','NON_EMPTY','NON_DEFAULT','USE_DEFAULTS','CUSTOM','NONE'] as const; type JsonIncludePolicy = typeof JSON_INCLUDE_POLICIES[number]; const isJsonIncludePolicy = (v: unknown): v is JsonIncludePolicy => typeof v === 'string' && (JSON_INCLUDE_POLICIES as readonly string[]).includes(v.trim().toUpperCase());
Try / catch
catch (IllegalArgumentException e) {
// message names the extension and the bad value — fix the spec and regenerate
throw new RuntimeException("Spec fix needed: " + e.getMessage(), e);
} Prevention
- Use exact JsonInclude.Include enum names with underscores; case-insensitive but not hyphen-tolerant.
- Keep a snippet/cheat-sheet of allowed extension values next to your spec linting config.
When it happens
Trigger: Adding x-jackson-json-include-policy: non-null (hyphen instead of underscore), if_present, or NEVER to a schema property in the OpenAPI spec and generating with -g spring or -g kotlin-spring. Values are matched case-insensitively after trim, but only exact enum names parse.
Common situations: Writing Jackson annotation values from memory with hyphens or wrong casing of words ('non-null', 'use-defaults'); copying Jackson 2.x vs 3.x enum names; a misspelled extension value silently present in a large spec until generation fails.
Related errors
- {} must be one of SKIP, FAIL, or NONE (to emit no annotation
- {} must be one of [NON_NULL, NON_EMPTY, NON_DEFAULT, NONE] b
- {} must be one of [SKIP, FAIL] but was: {}
- useJackson3 is only available with Spring Boot >= 4
- Currently, reactive option doesn't supported by Spring Cloud
AI-assisted analysis of OpenAPITools/openapi-generator@fcec517be3 (2026-08-22).
Data as JSON: /api/errors/a776336ac3fac048.
Report an issue: GitHub.