apache/pulsar · error · IllegalArgumentException

Schema should not be null.

Error message

Schema should not be null.

What it means

FunctionRecord.from(context, schema) builds a Record for output from the current function context. The schema is mandatory because the output record must know how to serialize its value; passing null is rejected with IllegalArgumentException.

Source

Thrown at pulsar-functions/api-java/src/main/java/org/apache/pulsar/functions/api/utils/FunctionRecord.java:63

        /**
         * Force to use {@link #from(Context, Schema)}.
         */
        private FunctionRecordBuilder() {}
    }

    /**
     * Creates a builder for a Record from a Function Context.
     * The builder is initialized with the output topic from the Context and with the topicName, key, eventTime,
     * properties, partitionId, partitionIndex and recordSequence from the Context input Record.
     * It doesn't initialize a Message at the moment.
     *
     * @param context a Function Context
     * @param <T> type of Record to build
     * @return a Record builder initialised with values from the Function Context
     */
    public static <T> FunctionRecord.FunctionRecordBuilder<T> from(Context context, Schema<T> schema) {
        if (schema == null) {
            throw new IllegalArgumentException("Schema should not be null.");
        }
        Record<?> currentRecord = context.getCurrentRecord();
        FunctionRecordBuilder<T> builder = new FunctionRecordBuilder<T>()
            .schema(schema)
            .destinationTopic(context.getOutputTopic())
            .properties(currentRecord.getProperties());
        currentRecord.getTopicName().ifPresent(builder::topicName);
        currentRecord.getKey().ifPresent(builder::key);
        currentRecord.getEventTime().ifPresent(builder::eventTime);
        currentRecord.getPartitionId().ifPresent(builder::partitionId);
        currentRecord.getPartitionIndex().ifPresent(builder::partitionIndex);
        currentRecord.getRecordSequence().ifPresent(builder::recordSequence);

        return builder;
    }

    @Override
    public T getValue() {

View on GitHub (pinned to 820761864e)

Solutions

  1. Pass an explicit schema, e.g. Schema.STRING, Schema.AVRO(MyPojo.class), or Schema.JSON(MyPojo.class)
  2. If the schema is dynamic, resolve it before calling from() and fail early with a clear message
  3. Use the schema inferred for your type rather than null

Example fix

// before
FunctionRecord.from(context, null); // throws
// after
FunctionRecord.from(context, Schema.JSON(MyPojo.class));
Defensive patterns

Strategy: validation

Validate before calling

if (schema == null) {
    throw new IllegalArgumentException("schema must be provided before FunctionRecord.from()");
}

Try / catch

try {
    builder = FunctionRecord.from(context, schema);
} catch (IllegalArgumentException e) {
    builder = FunctionRecord.from(context, Schema.STRING);
}

Prevention

When it happens

Trigger: Calling FunctionRecord.from(ctx, null), e.g. when a schema variable is conditionally unset, or calling the overload without a schema expecting defaults.

Common situations: Refactoring functions that changed from typed to schema-less output, generics erasing the schema selection, or copying example code that relied on a later builder.schema(...) call.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


AI-assisted analysis of apache/pulsar@820761864e (2026-09-06). Data as JSON: /api/errors/15158e63259a35c9. Report an issue: GitHub.