{"record":{"id":"1f7b64155350060f","repo":"pentaho/pentaho-kettle","slug":"element-getname-has-a-null-id","errorCode":null,"errorMessage":"\" + element.getName() + \" has a null id","messagePattern":"\" \\+ element\\.getName\\(\\) \\+ \" has a null id","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"warning","filePath":"plugins/pur/core/src/main/java/org/pentaho/di/repository/pur/PurRepository.java","lineNumber":2840,"sourceCode":"    }\n  }\n\n  private void updateSharedObjectCache( final RepositoryElementInterface element ) throws KettleException {\n    updateSharedObjectCache( element, null, null );\n  }\n\n  private void removeFromSharedObjectCache( final RepositoryObjectType type, final ObjectId id )\n    throws KettleException {\n    updateSharedObjectCache( null, type, id );\n  }\n\n  /**\n   * Do not call this method directly. Instead call updateSharedObjectCache or removeFromSharedObjectCache.\n   */\n  private void updateSharedObjectCache( final RepositoryElementInterface element, final RepositoryObjectType type,\n                                        final ObjectId id ) throws KettleException {\n    if ( element != null && ( element.getObjectId() == null || element.getObjectId().getId() == null ) ) {\n      throw new IllegalArgumentException( element.getName() + \" has a null id\" );\n    }\n\n    readWriteLock.readLock().lock();\n    sharedObjectsLock.writeLock().lock();\n\n    loadAndCacheSharedObjects( false );\n\n    boolean remove = element == null;\n    ObjectId idToFind = element != null ? element.getObjectId() : id;\n    RepositoryObjectType typeToUpdate = element != null ? element.getRepositoryElementType() : type;\n    RepositoryElementInterface elementToUpdate = null;\n    List<? extends SharedObjectInterface<?>> origSharedObjects = null;\n    try {\n      switch ( typeToUpdate ) {\n        case DATABASE:\n          origSharedObjects = sharedObjectsByType.get( RepositoryObjectType.DATABASE );\n          if ( !remove ) {\n            elementToUpdate = (RepositoryElementInterface) ( (DatabaseMeta) element ).deepClone( true );","sourceCodeStart":2822,"sourceCodeEnd":2858,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/plugins/pur/core/src/main/java/org/pentaho/di/repository/pur/PurRepository.java#L2822-L2858","documentation":"PurRepository.updateSharedObjectCache throws IllegalArgumentException when passed a repository element whose ObjectId or its id string is null. Cached shared objects must be identifiable by id; a null id indicates an element that was never persisted or was not properly initialized.","triggerScenarios":"Calling updateSharedObjectCache (directly or via save/update flows) with an element constructed in memory that has not been assigned an ObjectId by the repository — e.g. saving a new DatabaseMeta/PartitionSchema/SlaveServer whose id was never set.","commonSituations":"Creating a new shared object in code and attempting to cache/update it before calling repository.save; cloning elements that lose their id; loading elements from a non-pur repository and reusing them with a pur repository.","solutions":["Call repository.save(element) first so the repository assigns an ObjectId before caching","Check element.getObjectId() != null before invoking cache update paths","Re-load the element from the repository instead of reusing an unpersisted in-memory copy","Ensure clones preserve the ObjectId if that is intended"],"exampleFix":"// before\nDatabaseMeta db = new DatabaseMeta();\nrepo.updateSharedObjectCache(db, RepositoryObjectType.DATABASE, db.getObjectId()); // throws\n// after\nDatabaseMeta db = new DatabaseMeta();\nrepo.save(db, null); // assigns ObjectId\nif (db.getObjectId() != null) {\n  repo.updateSharedObjectCache(db, RepositoryObjectType.DATABASE, db.getObjectId());\n}","handlingStrategy":"type-guard","validationCode":"if (element != null && element.getObjectId() != null && element.getObjectId().getId() != null) {\n  // safe to proceed\n}","typeGuard":"boolean hasPersistedId(RepositoryElementInterface el) {\n  return el != null && el.getObjectId() != null && el.getObjectId().getId() != null;\n}","tryCatchPattern":"try {\n  cacheUpdate(element, type, id);\n} catch (IllegalArgumentException e) {\n  if (e.getMessage().endsWith(\"has a null id\")) {\n    // persist element first, then retry\n  } else { throw e; }\n}","preventionTips":["Always repository.save() new elements before cache/update operations","Check getObjectId() after save — it is assigned by the repository","Avoid reusing elements loaded from a different repository implementation","Ensure clone() implementations preserve ObjectId where intended"],"tags":["pentaho-kettle","repository","shared-objects","precondition"],"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"}