Activiti/Activiti · error · ActivitiIllegalArgumentException
Variable of type ' ' is not allowed in JsonPatch mapping…
Error message
Variable %s of type '%s' is not allowed in JsonPatch mapping. Only string and integer types are allowed
What it means
Thrown by replaceVariableIfSupported when a variable referenced in a JSON Patch mapping path has a type other than string or integer. Only those two types are supported for placeholder substitution in patch paths; other types (boolean, date, json, etc.) are rejected to avoid ambiguous path rendering.
Solutions
- Change the variable's declared type to string or integer in the process/extensions definition
- Convert the value into a new string/integer variable and reference that in the patch path
- Cast the incoming connector output to a supported type before storing it in the variable
Example fix
// before
execution.setVariable("orderId", 12345L); // long type
// after
execution.setVariable("orderId", String.valueOf(12345L)); // string type Defensive patterns
Strategy: validation
Validate before calling
VariableDefinition def = extensions.getPropertyByName("orderId");
String t = def.getType().toLowerCase();
if (!("string".equals(t) || "integer".equals(t))) throw new IllegalStateException("orderId type must be string or integer"); Type guard
boolean patchSafeType(VariableDefinition d) {
String t = d.getType() == null ? "" : d.getType().toLowerCase();
return "string".equals(t) || "integer".equals(t);
} Try / catch
try {
outcome = task.complete();
} catch (ActivitiIllegalArgumentException e) {
if (e.getMessage().contains("Only string and integer types are allowed")) {
// convert the variable to a supported type and retry
}
} Prevention
- Declare variables used in JSON Patch paths explicitly as string or integer in the model
- Avoid type-changing refactors on variables referenced by mappings
- Convert non-supported types (long, boolean, date) into helper string variables before mapping
When it happens
Trigger: An output mapping path like '/items/$orderId' where 'orderId' is defined but its variable type (per the extensions/variable definition) is e.g. boolean, long, or date.
Common situations: Changing a variable's type in the model (e.g. integer to long) without updating the mapping; the variable was auto-created with an inferred type; migrating from an older process version where the variable was a string.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- JSON_PATCH_MAPPING_ERROR
- Path variable $ used in JsonPatch mapping is not defined…
- Path variable $ used in JsonPatch mapping should not be…
- _ACTIVITI_SKIP_EXPRESSION_ENABLED variable does not resolve…
- Cannot coerce ' ' of to (incompatible type)
AI-assisted analysis of Activiti/Activiti@56435b1a97 (2026-09-09).
Data as JSON: /api/errors/083d7f37e7e322d8.
Report an issue: GitHub.
Appendix: source
Thrown at activiti-core/activiti-api-impl/activiti-api-process-runtime-impl/src/main/java/org/activiti/runtime/api/impl/ExtensionsVariablesMappingProvider.java:289
}
VariableDefinition propertyObj = extensions.getPropertyByName(variableName);
return replaceVariableIfSupported(propertyObj.getValue(), propertyObj.getType(), variableName);
}
private String replaceVariableIfSupported(Object value, String type, String originalProperty) {
if (value == null || StringUtils.isBlank(value.toString())) {
throw new ActivitiIllegalArgumentException(
String.format("Path variable $%s used in JsonPatch mapping should not be empty", originalProperty)
);
}
String typeLowerCase = type.toLowerCase();
if ("string".equals(typeLowerCase) || "integer".equals(typeLowerCase)) {
return value.toString();
}
throw new ActivitiIllegalArgumentException(
String.format(
"Variable %s of type '%s' is not allowed in JsonPatch mapping. Only string and integer types are allowed",
originalProperty,
type
)
);
}
private void initializePath(JsonNode oldNode, JsonNode patchNode) {
for (JsonNode patch : patchNode) {
String path = patch.get("path").asString();
String[] properties = path.split("/");
JsonNode currentNode = oldNode;
for (int i = 1; i < properties.length; i++) {
String property = properties[i];
if (isArrayElementPath(i, properties, property)) {View on GitHub (pinned to 56435b1a97)