pentaho/pentaho-kettle · error · pentaho.lang.OperationInvalidError
Merge operation ' ' is not defined.
Error message
Merge operation '${op}' is not defined. What it means
`__mergeOne` in pentaho/util/spec.js performs a named merge operation (replace, merge, etc.) on a target property. If the operation name (from the value's `__mergeOp` or the spec) is not a registered handler in `_mergeHandlers`, it throws OperationInvalidError. This guards against typos or unsupported custom ops.
Solutions
- Correct the operation name to a registered handler (e.g. 'replace' or 'merge')
- Register a custom handler in _mergeHandlers before calling merge with that op
- Log available op names to verify the expected value
Example fix
// before
var spec = { width: { value: 100, __mergeOp: "overwrite" } };
// after
var spec = { width: { value: 100, __mergeOp: "replace" } }; Defensive patterns
Strategy: validation
Validate before calling
var KNOWN_OPS = Object.keys(require("pentaho/util/spec")._mergeHandlers || {});
if (op && !KNOWN_OPS.includes(op)) throw new Error("Unknown merge op: " + op); Type guard
function isKnownMergeOp(op) { return typeof op === "string" && ["replace","merge"].includes(op); } Try / catch
try { merge(target, source); } catch (e) { if (e instanceof OperationInvalidError) { console.error("Bad __mergeOp in", source); } throw e; } Prevention
- Only use documented __mergeOp values (replace, merge)
- After upgrading, verify custom merge handlers are still registered
When it happens
Trigger: Merging a spec/source value whose merge operation name is misspelled (e.g. `__mergeOp: "mrege"`) or names an op that was never registered in `_mergeHandlers`.
Common situations: Typo in a `__mergeOp` annotation; custom merge handler removed or renamed in a version upgrade; passing an op string built dynamically at runtime.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- GPLoad.Exception.MatchColumnsNeeded
- No data output data type was specified for new field
- rule.select.module
- Script.Log.CouldNotAttachAdditionalScripts
- ScriptValuesMetaMod.Exception.FieldToReplaceNotFound
AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13).
Data as JSON: /api/errors/01b0293e202366d9.
Report an issue: GitHub.
Appendix: source
Thrown at plugins/core-ui/src/main/resources/app/pentaho/util/spec.js:102
// {$op: "merge", value: {}}
if((op = sourceValue.$op)) {
// Always deref source value, whether or not `op` is merge.
sourceValue = sourceValue.value;
// Merge operation only applies between two plain objects and
// add operation only applies between two arrays.
// Otherwise behaves like _replace_.
if(op === "merge" && !__isPlainJSObject(sourceValue) || op === "add" && !Array.isArray(sourceValue)) {
op = "replace";
}
} else {
op = "merge";
}
}
var handler = O.getOwn(_mergeHandlers, op || "replace");
if(!handler)
throw new OperationInvalidError("Merge operation '" + op + "' is not defined.");
handler(target, name, sourceValue);
}
/**
* Performs the merge operation when the target value is also a plain object,
* or replaces it, if not.
*
* @param {object} target - The target object.
* @param {string} name - The source property name.
* @param {object} sourceValue - The source property value.
*
* @private
*/
function __mergeOperMerge(target, name, sourceValue) {
// Is `targetValue` also a plain object?
var targetValue = target[name];
if(__isPlainJSObject(targetValue))View on GitHub (pinned to f3058517a1)