OpenAPITools/openapi-generator · error · IllegalArgumentException
{} must be one of SKIP, FAIL, or NONE (to emit no annotation
Error message
{} must be one of SKIP, FAIL, or NONE (to emit no annotation), but was: {} What it means
JsonAnnotationPolicyUtils.resolveManualJsonSetterNulls validates the per-property 'x-jackson-json-setter-nulls' vendor extension used by the spring and kotlin-spring generators. Valid values are SKIP, FAIL, or NONE (emit no @JsonSetter annotation); null or blank also means NONE. Any other token throws IllegalArgumentException, prefixed with the extension name so the offending spec location is identifiable.
Source
Thrown at modules/openapi-generator/src/main/java/org/openapitools/codegen/utils/JsonAnnotationPolicyUtils.java:343
*
* @param rawValue the raw vendor extension value set directly on the property in the spec
* @param extensionName the vendor extension key, used in the error message
* @return the normalized {@link JsonSetterNullsMode}: {@code SKIP}/{@code FAIL} to emit that annotation, or
* {@link JsonSetterNullsMode#NONE} when the override means "emit no annotation" ({@code NONE}/blank)
* @throws IllegalArgumentException when the override is not {@code SKIP}, {@code FAIL}, or {@code NONE}
*/
public static JsonSetterNullsMode resolveManualJsonSetterNulls(Object rawValue, String extensionName) {
if (rawValue == null) {
return JsonSetterNullsMode.NONE;
}
String trimmed = rawValue.toString().trim();
if (trimmed.isEmpty()) {
return JsonSetterNullsMode.NONE;
}
try {
return JsonSetterNullsMode.valueOf(trimmed.toUpperCase(java.util.Locale.ROOT));
} catch (IllegalArgumentException e) {
throw new IllegalArgumentException(extensionName
+ " must be one of SKIP, FAIL, or NONE (to emit no annotation), but was: " + rawValue);
}
}
/**
* Resolve the {@code @JsonSetter(nulls = ...)} annotation for a property into the
* {@code x-has-json-setter-nulls-skip}/{@code -fail} vendor extension the templates emit, mutating
* {@code property.vendorExtensions} and {@code model.imports} in place. Precedence (mirrors
* {@link #resolveJsonIncludePolicy}):
* <ol>
* <li>A per-property {@code x-jackson-json-setter-nulls} override in the spec always wins and is honored
* unconditionally (regardless of {@code generateJsonSetterNullsAnnotations}, required/nullable,
* {@code openApiNullable}, or {@code failModeSupported}).</li>
* <li>Otherwise the automatic optional-non-nullable mode from
* {@link #resolveJsonSetterNullsMode(TriStateBoolean, boolean, boolean, boolean, boolean, JsonSetterNullsMode)}.</li>
* </ol>
*
* @param model the model owning {@code property}, whose imports may be extendedView on GitHub (pinned to fcec517be3)
Solutions
- Set the extension to SKIP, FAIL, or NONE exactly (underscores not needed; case-insensitive).
- Remove the extension to inherit the generator-wide optionalNonNullPropertyJsonSetterNulls / openApiNullable-derived behavior.
- Grep the spec for x-jackson-json-setter-nulls and check each value against the three allowed tokens.
Example fix
# before (openapi.yaml)
x-jackson-json-setter-nulls: skip-nulls
# after
x-jackson-json-setter-nulls: SKIP Defensive patterns
Strategy: validation
Validate before calling
// Node: validate x-jackson-json-setter-nulls values in the spec
const ALLOWED = new Set(['SKIP','FAIL','NONE','']);
const check = (o) => { for (const [k, v] of Object.entries(o ?? {})) {
if (k === 'x-jackson-json-setter-nulls' && !ALLOWED.has(String(v).trim().toUpperCase()))
throw new Error(`invalid x-jackson-json-setter-nulls: ${v}`);
if (v && typeof v === 'object') check(v);
}};
check(require('./openapi.json')); Type guard
const isJsonSetterNulls = (v: unknown): v is 'SKIP' | 'FAIL' | 'NONE' => typeof v === 'string' && ['SKIP','FAIL','NONE'].includes(v.trim().toUpperCase());
Prevention
- Only three tokens are valid: SKIP, FAIL, NONE — no hyphens or prose.
- Remove the extension when you want inherited behavior instead of writing 'default'.
When it happens
Trigger: Adding x-jackson-json-setter-nulls: skip-nulls, ignore, or ALWAYS to a schema property and generating with -g spring / -g kotlin-spring. Matching is trim + uppercase + valueOf, so 'skip' and 'Skip' parse, but hyphenated or free-text values do not.
Common situations: Spec authors paraphrasing Jackson documentation ('nulls = Nulls.SKIP' pasted verbatim); consistent-value policies where one property in a big spec has a typo; converting JSON examples with lowercase-hyphen style into YAML extension values.
Related errors
- {} must be a valid com.fasterxml.jackson.annotation.JsonIncl
- {} 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/3c75c362a18f6c3e.
Report an issue: GitHub.