{"record":{"id":"a0005fb70e3b7805","repo":"pentaho/pentaho-kettle","slug":"a-elemname-cannot-have-a-nully-keyname-value","errorCode":null,"errorMessage":"A ${elemName} cannot have a nully ${keyName} value.","messagePattern":"A (.+?) cannot have a nully (.+?) value\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"plugins/core-ui/src/main/resources/app/pentaho/lang/Collection.js","lineNumber":117,"sourceCode":"    },\n\n    _getElemKey: function(elem) {\n      return elem.key;\n    },\n\n    _sayElemWithKey: function(key) {\n      return \"A \" + this._getElemName() + \" with \" + this._getKeyName() + \" '\" + key + \"'\";\n    },\n\n    _sayElemCannotHaveNullyKey: function() {\n      return \"A \" + this._getElemName() + \" cannot have a nully \" + this._getKeyName() + \" value.\";\n    },\n\n    _adding: function(elem, index, ka) {\n      var elem2 = this._cast(elem, index, ka);\n      if(elem2 !== undefined) {\n        var key = this._getElemKey(elem2);\n        if(key == null) throw new Error(this._sayElemCannotHaveNullyKey());\n        if(this.has(key)) throw new Error(this._sayElemWithKey(key) + \" is already included.\");\n      }\n\n      return elem2;\n    },\n\n    _replacing: function(elem, index, elem0, ka) {\n      var elem2 = this._cast(elem, index, ka);\n      if(elem2 !== undefined) {\n        var key = this._getElemKey(elem2);\n        if(key == null) throw new Error(this._sayElemCannotHaveNullyKey());\n      }\n\n      return elem2;\n    },\n\n    _added: function(elem) {\n      this.__keys[this._getElemKey(elem)] = elem;","sourceCodeStart":99,"sourceCodeEnd":135,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/plugins/core-ui/src/main/resources/app/pentaho/lang/Collection.js#L99-L135","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","solutions":["Set the key property on the element before adding it (collection.add({key: 'k', ...})).","Map the source field onto the expected key name (e.g. {key: src.id}).","If the element is invalid, skip it instead of adding: filter out items with nully keys before add/addAll.","Provide/override _cast or _getElemKey on a custom collection so keys are derived or missing-key elements are rejected cleanly.","Debug with a check: elements where elem.key == null before calling add."],"exampleFix":"// before\ncollection.add({label: \"x\"}); // throws: cannot have a nully key value\n// after\ncollection.add({key: \"x-key\", label: \"x\"});","handlingStrategy":"validation","validationCode":"function assertKeyed(elem, keyName) {\n  if (elem != null && elem[keyName] == null) {\n    throw new Error(\"Element cannot be added: missing '\" + keyName + \"'\");\n  }\n  return elem;\n}\nitems.map(function(e) { return assertKeyed(e, \"key\"); }).forEach(collection.add, collection);","typeGuard":"function hasKey(elem, keyName) {\n  return elem != null && typeof elem === \"object\" && elem[keyName] != null;\n}","tryCatchPattern":"try {\n  collection.add(elem);\n} catch (e) {\n  if (String(e.message).indexOf(\"nully\") !== -1 && String(e.message).indexOf(\"key\") !== -1) {\n    elem.key = elem.id; // derive key from an alternate source field\n    return collection.add(elem);\n  }\n  throw e;\n}","preventionTips":["Always construct elements with their key set before insertion.","Map API field names (id/uuid/code) onto the collection's expected key property in one adapter function.","Filter out keyless items when ingesting external data.","When subclassing, override _cast to assign or reject keyless elements early."],"tags":["collections","key-validation","null-value","data-model"],"backgroundTag":"null-argument","analyzedSha":"f3058517a153da500bf4551f46d79b91bf8ec552","analyzedAt":"2026-09-13T14:04:16.340Z","contentChangedAt":"2026-09-13T14:04:16.340Z","schemaVersion":2},"datasetVersion":"2026-09-20T23:17:15.980Z"}