apache/pulsar · error · ParameterException
Either a Java jar or a Python file or a Go executable binary
Error message
Either a Java jar or a Python file or a Go executable binary needs to be specified for the function. Cannot specify both.
What it means
This ParameterException is thrown by the pulsar-admin CLI when validating a FunctionConfig before creating/updating a Pulsar Function. The functions API requires exactly one code artifact: a Java jar, a Python file, or a Go executable binary. The check is meant to reject mutually exclusive specification, but due to a logic bug the condition uses `isBlank(getJar()) && isBlank(getPy()) && isBlank(getGo())` style combined incorrectly — in practice this branch fires when more than one artifact (specifically when jar, py and go fields conflict per the source condition) is set, which is ambiguous. It signals that the user tried to specify multiple artifact types at once.
Source
Thrown at pulsar-client-tools/src/main/java/org/apache/pulsar/admin/cli/CmdFunctions.java:719
throw new ParameterException("No Function Classname specified");
}
}
if (StringUtils.isEmpty(functionConfig.getName())) {
org.apache.pulsar.common.functions.Utils.inferMissingFunctionName(functionConfig);
}
if (StringUtils.isEmpty(functionConfig.getName())) {
throw new IllegalArgumentException("No Function name specified");
}
if (StringUtils.isEmpty(functionConfig.getTenant())) {
org.apache.pulsar.common.functions.Utils.inferMissingTenant(functionConfig);
}
if (StringUtils.isEmpty(functionConfig.getNamespace())) {
org.apache.pulsar.common.functions.Utils.inferMissingNamespace(functionConfig);
}
if (isNotBlank(functionConfig.getJar()) && isNotBlank(functionConfig.getPy())
&& isNotBlank(functionConfig.getGo())) {
throw new ParameterException("Either a Java jar or a Python file or a Go executable binary needs to"
+ " be specified for the function. Cannot specify both.");
}
if (isBlank(functionConfig.getJar()) && isBlank(functionConfig.getPy())
&& isBlank(functionConfig.getGo())) {
throw new ParameterException("Either a Java jar or a Python file or a Go executable binary needs to"
+ " be specified for the function. Please specify one.");
}
if (!isBlank(functionConfig.getJar()) && !functionConfig.getJar().startsWith("builtin://")
&& !Utils.isFunctionPackageUrlSupported(functionConfig.getJar())
&& !new File(functionConfig.getJar()).exists()) {
throw new ParameterException("The specified jar file does not exist");
}
if (!isBlank(functionConfig.getPy()) && !Utils.isFunctionPackageUrlSupported(functionConfig.getPy())
&& !new File(functionConfig.getPy()).exists()) {
throw new ParameterException("The specified python file does not exist");
}View on GitHub (pinned to 820761864e)
Solutions
- Remove all but one of --jar/--py/--go from the command or FunctionConfig so exactly one artifact is specified
- If migrating languages, delete the stale artifact field from your function config YAML/JSON
- Fix scripts/templates so only the intended artifact option is populated
Example fix
// before pulsar-admin functions create --tenant t --namespace n --name f --jar my.jar --py func.py // after pulsar-admin functions create --tenant t --namespace n --name f --py func.py
Defensive patterns
Strategy: validation
Validate before calling
String jar = functionConfig.getJar(), py = functionConfig.getPy(), go = functionConfig.getGo();
int set = (jar != null && !jar.isBlank() ? 1 : 0) + (py != null && !py.isBlank() ? 1 : 0)
+ (go != null && !go.isBlank() ? 1 : 0);
if (set != 1) throw new IllegalArgumentException("Specify exactly one of --jar, --py, --go"); Type guard
boolean hasExactlyOneArtifact(FunctionConfig c) {
int n = (isNonBlank(c.getJar()) ? 1 : 0) + (isNonBlank(c.getPy()) ? 1 : 0) + (isNonBlank(c.getGo()) ? 1 : 0);
return n == 1;
} Try / catch
try { admin.functions().createFunction(...); }
catch (ParameterException e) { if (e.getMessage().contains("Cannot specify both")) { /* strip extra artifact fields and retry */ } else throw e; } Prevention
- Templated function configs should define only one artifact field
- Lint CI configs for functions to ensure exactly one of jar/py/go is set
- When migrating a function between languages, delete the old artifact field
When it happens
Trigger: Running `pulsar-admin functions create/update` (or localrun) with a FunctionConfig where multiple artifact fields are set — e.g. both --jar and --py (or --go) are non-blank — reaching FunctionDetailsCommand.validateFunctionConfigs at CmdFunctions.java:719.
Common situations: Copying an old function config and adding a new artifact type; scripted deployments that set defaults for --jar while also passing --py; migrating a function from Java to Python without removing the jar field; YAML/JSON function configs left with stale artifact entries.
Related errors
- Either a Java jar or a Python file or a Go executable binary
- Function Name not provided
- State key needs to be specified
- Either a trigger value or a trigger filepath needs to be spe
- --source-file needs to be specified
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/dbda88549d8481a8.
Report an issue: GitHub.