pentaho/pentaho-kettle · error · Error

A cannot have a nully value.

Error message

A ${elemName} cannot have a nully ${keyName} value.

What it means

Keyed collections in pentaho/lang/Collection validate every element during _adding. After casting (_cast) an element to add, the collection reads its key via _getElemKey (elem.key by default); if the key is null or undefined the element could never be addressed, so the collection refuses it with 'A <elemName> cannot have a nully <keyName> value.' (built by _sayElemCannotHaveNullyKey). Note the check only runs when _cast returns a defined element; undefined means the element was rejected/absorbed earlier.

Solutions

  1. Set the key property on the element before adding it (collection.add({key: 'k', ...})).
  2. Map the source field onto the expected key name (e.g. {key: src.id}).
  3. If the element is invalid, skip it instead of adding: filter out items with nully keys before add/addAll.
  4. Provide/override _cast or _getElemKey on a custom collection so keys are derived or missing-key elements are rejected cleanly.
  5. Debug with a check: elements where elem.key == null before calling add.

Example fix

// before
collection.add({label: "x"}); // throws: cannot have a nully key value
// after
collection.add({key: "x-key", label: "x"});
Defensive patterns

Strategy: validation

Validate before calling

function assertKeyed(elem, keyName) {
  if (elem != null && elem[keyName] == null) {
    throw new Error("Element cannot be added: missing '" + keyName + "'");
  }
  return elem;
}
items.map(function(e) { return assertKeyed(e, "key"); }).forEach(collection.add, collection);

Type guard

function hasKey(elem, keyName) {
  return elem != null && typeof elem === "object" && elem[keyName] != null;
}

Try / catch

try {
  collection.add(elem);
} catch (e) {
  if (String(e.message).indexOf("nully") !== -1 && String(e.message).indexOf("key") !== -1) {
    elem.key = elem.id; // derive key from an alternate source field
    return collection.add(elem);
  }
  throw e;
}

Prevention

When it happens

Trigger: Adding an element whose key property is null/undefined — e.g. collection.add({}) or add(elem) where elem.key was never set — via add/addAll/constructor element lists on a keyed collection subclass (using keyName).

Common situations: Building elements from API responses where the key field is missing or named differently; deserialization producing elements before their key is assigned; forgetting to set an id/key on a spec object; a cast implementation producing a keyless element.

Related errors


AI-assisted analysis of pentaho/pentaho-kettle@f3058517a1 (2026-09-13). Data as JSON: /api/errors/a0005fb70e3b7805. Report an issue: GitHub.

Appendix: source

Thrown at plugins/core-ui/src/main/resources/app/pentaho/lang/Collection.js:117

    },

    _getElemKey: function(elem) {
      return elem.key;
    },

    _sayElemWithKey: function(key) {
      return "A " + this._getElemName() + " with " + this._getKeyName() + " '" + key + "'";
    },

    _sayElemCannotHaveNullyKey: function() {
      return "A " + this._getElemName() + " cannot have a nully " + this._getKeyName() + " value.";
    },

    _adding: function(elem, index, ka) {
      var elem2 = this._cast(elem, index, ka);
      if(elem2 !== undefined) {
        var key = this._getElemKey(elem2);
        if(key == null) throw new Error(this._sayElemCannotHaveNullyKey());
        if(this.has(key)) throw new Error(this._sayElemWithKey(key) + " is already included.");
      }

      return elem2;
    },

    _replacing: function(elem, index, elem0, ka) {
      var elem2 = this._cast(elem, index, ka);
      if(elem2 !== undefined) {
        var key = this._getElemKey(elem2);
        if(key == null) throw new Error(this._sayElemCannotHaveNullyKey());
      }

      return elem2;
    },

    _added: function(elem) {
      this.__keys[this._getElemKey(elem)] = elem;

View on GitHub (pinned to f3058517a1)