{"record":{"id":"2af934d4875a7747","repo":"quarkusio/quarkus","slug":"timestamp-must-not-be-null-2af934","errorCode":null,"errorMessage":"`timestamp` must not be `null`","messagePattern":"`timestamp` must not be `null`","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"extensions/redis-client/runtime/src/main/java/io/quarkus/redis/datasource/value/SetArgs.java","lineNumber":70,"sourceCode":"     * Set the expiration timestamp as a number of seconds since the Unix epoch.\n     *\n     * @param timestamp the timestamp\n     * @return the current {@code SetArgs}\n     */\n    public SetArgs exAt(long timestamp) {\n        this.exAt = timestamp;\n        return this;\n    }\n\n    /**\n     * Set the expiration timestamp as a number of seconds since the Unix epoch.\n     *\n     * @param timestamp the timestamp\n     * @return the current {@code SetArgs}\n     */\n    public SetArgs exAt(Instant timestamp) {\n        if (timestamp == null) {\n            throw new IllegalArgumentException(\"`timestamp` must not be `null`\");\n        }\n        exAt(timestamp.toEpochMilli() / 1000);\n        return this;\n    }\n\n    /**\n     * Set the expiration timeout, in milliseconds.\n     *\n     * @param timeout expiration timeout in milliseconds\n     * @return the current {@code SetArgs}\n     */\n    public SetArgs px(long timeout) {\n        if (timeout < 0) {\n            throw new IllegalArgumentException(\"`timeout` must be positive\");\n        }\n        this.px = timeout;\n        return this;\n    }","sourceCodeStart":52,"sourceCodeEnd":88,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/redis-client/runtime/src/main/java/io/quarkus/redis/datasource/value/SetArgs.java#L52-L88","documentation":"SetArgs.exAt(Instant) sets expiration as a Unix-epoch timestamp in seconds. It rejects a null Instant with IllegalArgumentException so callers get a clear, immediate message rather than a NullPointerException from Instant.toEpochMilli().","triggerScenarios":"Calling SetArgs.exAt(null), e.g. when the expiry Instant comes from a nullable entity field, an absent header, or a parsing failure that returned null.","commonSituations":"Optional expiry attributes on domain objects, JSON payloads missing the expiry field, or clock/scheduling code that failed to compute an Instant.","solutions":["Ensure the Instant is non-null before calling exAt; substitute a computed default (e.g. Instant.now().plus(ttl)) when absent.","Use ex(Duration) or px(Duration) when you have a relative TTL instead of an absolute instant.","Fix the upstream parsing/lookup that produced the null Instant."],"exampleFix":"// before\nSetArgs args = new SetArgs().exAt(expiresAt); // may be null\n// after\nSetArgs args = new SetArgs().exAt(expiresAt != null ? expiresAt : Instant.now().plusSeconds(60));","handlingStrategy":"type-guard","validationCode":"Objects.requireNonNull(expiresAt, \"expiresAt must not be null\");\nSetArgs args = new SetArgs().exAt(expiresAt);","typeGuard":"static boolean isValidInstant(Instant ts) {\n    return ts != null && !ts.isBefore(Instant.now());\n}","tryCatchPattern":"try {\n    args = new SetArgs().exAt(expiresAt);\n} catch (IllegalArgumentException e) {\n    log.warn(\"Null expiry instant, defaulting to now+60s\");\n    args = new SetArgs().exAt(Instant.now().plusSeconds(60));\n}","preventionTips":["Normalize nullable expiry fields to a computed default at the domain layer.","Validate that parsed Instants from external input are non-null before use.","Prefer relative TTLs (ex/px with Duration) when an absolute timestamp is not truly required."],"tags":["redis","null-check","argument-validation"],"backgroundTag":"null-argument","analyzedSha":"e1c734241f34c7919086ceb4c9262b4a58f6de44","analyzedAt":"2026-09-05T17:01:29.979Z","contentChangedAt":"2026-09-05T17:01:29.979Z","schemaVersion":2},"datasetVersion":"2026-09-12T22:17:10.623Z"}