apache/pulsar · error · TypeConversionException

e.getMessage()

Error message

e.getMessage()

What it means

LocalRunner's FunctionConfigConverter converts a JSON command-line argument into a FunctionConfig via Jackson. If the JSON cannot be parsed or doesn't match FunctionConfig (IOException), it wraps e.getMessage() in jcommander's TypeConversionException, so localrun aborts with the raw Jackson message.

Source

Thrown at pulsar-functions/localrun/src/main/java/org/apache/pulsar/functions/LocalRunner.java:124

    public enum RuntimeEnv {
        THREAD,
        PROCESS
    }

    @Value
    private static class UserCodeClassLoader {
        ClassLoader classLoader;
        boolean classLoaderCreated;
    }

    public static class FunctionConfigConverter implements ITypeConverter<FunctionConfig> {
        @Override
        public FunctionConfig convert(String value) {
            try {
                return ObjectMapperFactory.getMapper().reader().readValue(value, FunctionConfig.class);
            } catch (IOException e) {
                throw new TypeConversionException(e.getMessage());
            }
        }
    }

    public static class SourceConfigConverter implements ITypeConverter<SourceConfig> {
        @Override
        public SourceConfig convert(String value) {
            try {
                return ObjectMapperFactory.getMapper().reader().readValue(value, SourceConfig.class);
            } catch (IOException e) {
                throw new TypeConversionException(e.getMessage());
            }
        }
    }

    public static class SinkConfigConverter implements ITypeConverter<SinkConfig> {
        @Override
        public SinkConfig convert(String value) {

View on GitHub (pinned to 820761864e)

Solutions

  1. Validate the JSON string (e.g. python3 -m json.tool) and fix syntax before running localrun.
  2. Quote the whole --functionConfig argument properly for your shell; read JSON from a file with $(cat config.json) if needed.
  3. Ensure field names and types match FunctionConfig (e.g. className, inputs, output).
  4. Read the TypeConversionException message — it is the raw Jackson parse error indicating the exact problem.

Example fix

# before
--functionConfig '{"className": myFunction}'   # invalid JSON
# after
--functionConfig '{"className":"com.example.MyFunction","inputs":["input-topic"],"output":"out-topic"}'
Defensive patterns

Strategy: try-catch

Validate before calling

python3 -c 'import json,sys; json.load(open(sys.argv[1]))' function-config.json  # validate before passing

Try / catch

try { ... } catch (ParameterException e) {
    if (e.getCause() instanceof TypeConversionException) {
        // fix the --functionConfig JSON; message is the Jackson parse error
    }
}

Prevention

When it happens

Trigger: Passing malformed JSON to --functionConfig on the pulsar-functions localrun command line (trailing commas, single quotes, non-JSON text, wrong field names/types).

Common situations: Shell quoting mangling the JSON (spaces/newlines); copy-pasted YAML instead of JSON; passing a file path instead of JSON content; mismatched field types like resources as strings.

Understand the failure class

Background: JSON parse error: "Unexpected token" / "not valid JSON" / "failed to parse" — what JSON parsers are really complaining about — this error's family across 45 libraries.

Related errors


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