{"record":{"id":"4ab8cfbffb237991","repo":"apache/flink","slug":"id-must-not-be-null","errorCode":null,"errorMessage":"Id must not be null.","messagePattern":"Id must not be null\\.","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"flink-core/src/main/java/org/apache/flink/util/AbstractID.java","lineNumber":79,"sourceCode":"    /**\n     * Constructs a new abstract ID.\n     *\n     * @param lowerPart the lower bytes of the ID\n     * @param upperPart the higher bytes of the ID\n     */\n    public AbstractID(long lowerPart, long upperPart) {\n        this.lowerPart = lowerPart;\n        this.upperPart = upperPart;\n    }\n\n    /**\n     * Copy constructor: Creates a new abstract ID from the given one.\n     *\n     * @param id the abstract ID to copy\n     */\n    public AbstractID(AbstractID id) {\n        if (id == null) {\n            throw new IllegalArgumentException(\"Id must not be null.\");\n        }\n        this.lowerPart = id.lowerPart;\n        this.upperPart = id.upperPart;\n    }\n\n    /** Constructs a new random ID from a uniform distribution. */\n    public AbstractID() {\n        ThreadLocalRandom random = ThreadLocalRandom.current();\n        this.lowerPart = random.nextLong();\n        this.upperPart = random.nextLong();\n    }\n\n    // --------------------------------------------------------------------------------------------\n\n    /**\n     * Gets the lower 64 bits of the ID.\n     *\n     * @return The lower 64 bits of the ID.","sourceCodeStart":61,"sourceCodeEnd":97,"githubUrl":"https://github.com/apache/flink/blob/2f3c205e9266cb30240eb7f4fdab15cad629a70f/flink-core/src/main/java/org/apache/flink/util/AbstractID.java#L61-L97","documentation":"Thrown by the copy constructor AbstractID(AbstractID id) when the argument is null. AbstractID is the base of Flink's JobID/AbstractID identifiers, and the copy constructor refuses to copy from nothing rather than producing a zeroed ID. It is a guard against programming errors at the call site.","triggerScenarios":"Calling `new AbstractID((AbstractID) null)` directly, or passing a variable that is null (e.g. an uninitialized JobGraph field, a lookup that returned null) to the copy constructor. Subclasses like JobID inherit the same constructor (`new JobID(nullJobID)`).","commonSituations":"Copying a JobID from a map/registry that did not contain the key; deserializing a request where the ID field was omitted; refactoring that leaves an ID unset in a test fixture.","solutions":["Null-check the source ID before calling the copy constructor and fail with a meaningful message at the correct layer","Trace where the null ID originates (map lookup, deserialization) and fix that producer","If an absent ID is legitimate, create a fresh random AbstractID() instead of copying null"],"exampleFix":"// before\nAbstractID copy = new AbstractID(someRegistry.get(jobName)); // may be null\n\n// after\nAbstractID original = someRegistry.get(jobName);\nif (original == null) {\n    throw new IllegalArgumentException(\"No ID registered for job \" + jobName);\n}\nAbstractID copy = new AbstractID(original);","handlingStrategy":"validation","validationCode":"if (sourceId == null) {\n    throw new IllegalArgumentException(\"Source AbstractID must not be null\");\n}\nAbstractID copy = new AbstractID(sourceId);","typeGuard":null,"tryCatchPattern":"catch (IllegalArgumentException e) only if a null ID can legitimately reach legacy call sites; otherwise fail fast at the producer and do not catch.","preventionTips":["Never pass registry/map lookups for IDs directly to the copy constructor; bind and null-check first","Use Optional.ofNullable(registry.get(k)).orElseThrow(...) with context at the lookup site"],"tags":["flink-core","validation","null-safety","id"],"backgroundTag":null,"analyzedSha":"2f3c205e9266cb30240eb7f4fdab15cad629a70f","analyzedAt":"2026-08-14T08:48:24.518Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}