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.

Solutions

  1. Set the extension to SKIP, FAIL, or NONE exactly (underscores not needed; case-insensitive).
  2. Remove the extension to inherit the generator-wide optionalNonNullPropertyJsonSetterNulls / openApiNullable-derived behavior.
  3. 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

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


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

Appendix: 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 extended

View on GitHub (pinned to fcec517be3)