FasterXML/jackson-databind · error · IllegalArgumentException

Cannot use FormatSchema of type {} for format {}

Error message

Cannot use FormatSchema of type {} for format {}

What it means

ObjectWriter._verifySchemaType() mirrors the reader-side guard: before serializing with a FormatSchema, it confirms the schema is usable by the writer's generator factory (e.g. a CsvSchema must go with a CsvFactory/CSV generator). If the schema doesn't match the configured dataformat, it throws IllegalArgumentException naming the schema class and the expected format name. This prevents writing malformed output to the wrong backend.

Source

Thrown at src/main/java/tools/jackson/databind/ObjectWriter.java:1279

    /**
     * Overridable helper method used for constructing
     * {@link SerializationContext} to use for serialization.
     */
    protected final SerializationContextExt _serializationContext() {
        return _serializationContexts.createContext(_config, _generatorSettings);
    }

    /*
    /**********************************************************************
    /* Internal methods
    /**********************************************************************
     */

    protected void _verifySchemaType(FormatSchema schema)
    {
        if (schema != null) {
            if (!_generatorFactory.canUseSchema(schema)) {
                    throw new IllegalArgumentException("Cannot use FormatSchema of type "+schema.getClass().getName()
                            +" for format "+_generatorFactory.getFormatName());
            }
        }
    }

    /**
     * Helper method that applies configured {@link GeneratorInitializer},
     * if any, to the given generator and returns it.
     *
     * @since 3.2
     */
    protected JsonGenerator _initializeGenerator(JsonGenerator gen) {
        GeneratorInitializer init = _config.getGeneratorInitializer();
        if (init != null) {
            init.initialize(_config, gen);
        }
        return gen;
    }

View on GitHub (pinned to a50c7d2a1d)

Solutions

  1. Obtain both the writer and the schema from the same format-specific mapper (CsvMapper, YAMLMapper, AvroMapper).
  2. Use mapper.writer(schema) only on the mapper whose tokenStreamFactory().canUseSchema(schema) returns true.
  3. Cache schema + writer together as a pair to avoid cross-wiring.
  4. In DI, qualify the mapper beans (@Qualifier) so the schema-bearing component gets the right one.

Example fix

// before
JsonMapper m = JsonMapper.builder().build();
CsvSchema csv = CsvSchema.emptySchema().withHeader();
m.writer(csv).writeValue(out, rows); // throws
// after
CsvMapper m = CsvMapper.builder().build();
CsvSchema csv = m.schemaFor(Row.class).withHeader();
m.writer(csv).writeValue(out, rows);
Defensive patterns

Strategy: validation

Validate before calling

if (schema != null && !mapper.tokenStreamFactory().canUseSchema(schema)) {
    throw new IllegalArgumentException("schema mismatch");
}
mapper.writer(schema).writeValue(out, value);

Type guard

boolean schemaMatchesWriter(JsonMapper m, FormatSchema s) {
    return s != null && m.tokenStreamFactory().canUseSchema(s);
}

Try / catch

try {
    mapper.writer(schema).writeValue(out, value);
} catch (IllegalArgumentException e) {
    if (e.getMessage().startsWith("Cannot use FormatSchema")) {
        // switch to the format-specific mapper for this schema
    }
    throw e;
}

Prevention

When it happens

Trigger: Calling writer.withSchema(csvSchema) on a writer from a JsonMapper; passing an AvroSchema to a JSON generator; reusing a schema object cached from a different mapper after switching dataformats; generic 'write with schema' helper that accepts any FormatSchema and forwards it.

Common situations: Multiple format-specific writers in one app and a schema wired to the wrong one via DI; module upgrade where the schema class identity changed; copy-paste of a working CSV write but forgetting to also switch the mapper to CsvMapper; a shared ObjectMapper bean used for both JSON and CSV inadvertently.

Related errors


AI-assisted analysis of FasterXML/jackson-databind@a50c7d2a1d (2026-08-06). Data as JSON: /api/errors/295d4a514a9cf0b2. Report an issue: GitHub.