{"record":{"id":"92a2b2afe8005644","repo":"jwtk/jjwt","slug":"i-getclass-getid-cannot-be-null-or-empty","errorCode":null,"errorMessage":"${i.getClass()} getId() cannot be null or empty.","messagePattern":"(.+?) getId\\(\\) cannot be null or empty\\.","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"impl/src/main/java/io/jsonwebtoken/impl/lang/NestedIdentifiableCollection.java","lineNumber":53,"sourceCode":"    private final P PARENT;\n    private final Map<String, E> VALUES;\n\n    private static <K, V> Map<K, V> nullSafe(Map<K, V> m) {\n        return m == null ? Collections.<K, V>emptyMap() : m;\n    }\n\n    public NestedIdentifiableCollection(P parent, Map<String, ? extends E> seed) {\n        super();\n        this.PARENT = Assert.notNull(parent, \"parent cannot be null.\");\n        this.VALUES = new LinkedHashMap<>(nullSafe(seed));\n    }\n\n    protected final String assertId(E i) {\n        Assert.notNull(i, \"Identifiable instance cannot be null.\");\n        String id = i.getId();\n        if (!Strings.hasText(id)) {\n            String msg = i.getClass() + \" getId() cannot be null or empty.\";\n            throw new IllegalArgumentException(msg);\n        }\n        return id;\n    }\n\n    private boolean doAdd(E e) {\n        String id = assertId(e);\n        this.VALUES.put(id, e);\n        return true;\n    }\n\n    @Override\n    public NestedCollection<E, P> add(E e) {\n        if (e != null) {\n            doAdd(e);\n            changed();\n        }\n        return this;\n    }","sourceCodeStart":35,"sourceCodeEnd":71,"githubUrl":"https://github.com/jwtk/jjwt/blob/fb71496164c71442d08adec4571d9616ed5e1b8d/impl/src/main/java/io/jsonwebtoken/impl/lang/NestedIdentifiableCollection.java#L35-L71","documentation":"NestedIdentifiableCollection.assertId validates that every element added to the collection implements Identifiable and returns a non-null, non-empty id via getId(). If the id is missing, an IllegalArgumentException naming the element's class is thrown. This guards collection identity integrity.","triggerScenarios":"Adding an Identifiable element whose getId() returns null or \"\" to a NestedIdentifiableCollection (e.g. via add/doAdd), or passing a null element.","commonSituations":"Custom Identifiable implementations that lazily assign ids; deserialized objects with ids not yet populated; builder misuse where an id setter was skipped.","solutions":["Set a non-empty id on the object before adding it to the collection.","Ensure getId() never returns null/empty once the object is constructed (assign in constructor or builder).","Validate the id with a hasText check before calling add()."],"exampleFix":"// before\nmyIdentifiable.setId(\"\");\ncollection.add(myIdentifiable);\n// after\nmyIdentifiable.setId(\"unique-key-1\");\ncollection.add(myIdentifiable);","handlingStrategy":"validation","validationCode":"void safeAdd(Collection<E> c, E item) {\n    if (item == null || item.getId() == null || item.getId().isBlank()) {\n        throw new IllegalArgumentException(\"Item must have a non-empty id before adding\");\n    }\n    c.add(item);\n}","typeGuard":null,"tryCatchPattern":"try {\n    collection.add(item);\n} catch (IllegalArgumentException e) {\n    if (e.getMessage() != null && e.getMessage().endsWith(\"getId() cannot be null or empty.\")) {\n        // assign an id and retry or report\n    }\n    throw e;\n}","preventionTips":["Assign ids in the constructor or builder so Identifiable objects are never id-less","Assert non-empty ids right after deserialization","Avoid lazy id generation in getters"],"tags":["collection","identifier","validation"],"backgroundTag":"empty-required-field","analyzedSha":"fb71496164c71442d08adec4571d9616ed5e1b8d","analyzedAt":"2026-09-09T00:33:09.982Z","contentChangedAt":"2026-09-09T00:33:09.982Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}