{"record":{"id":"698c1d527a5aefe7","repo":"redisson/redisson","slug":"expiration-must-not-be-null","errorCode":null,"errorMessage":"Expiration must not be null!","messagePattern":"Expiration must not be null!","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"redisson-spring/redisson-spring-data/redisson-spring-data-20/src/main/java/org/redisson/spring/data/connection/RedissonReactiveStringCommands.java","lineNumber":183,"sourceCode":"            byte[] keyBuf = toByteArray(command.getKey());\n            byte[] valueBuf = toByteArray(command.getValue());\n            \n            Mono<Boolean> m = write(keyBuf, StringCodec.INSTANCE, RedisCommands.SETNX, keyBuf, valueBuf);\n            return m.map(v -> new BooleanResponse<>(command, v));\n        });\n    }\n\n    private static final RedisCommand<Boolean> SETEX = new RedisCommand<Boolean>(\"SETEX\", new BooleanReplayConvertor());\n    \n    @Override\n    public Flux<BooleanResponse<SetCommand>> setEX(Publisher<SetCommand> commands) {\n        return execute(commands, command -> {\n\n            Assert.notNull(command.getKey(), \"Key must not be null!\");\n            Assert.notNull(command.getValue(), \"Value must not be null!\");\n\n            if (!command.getExpiration().isPresent()) {\n                throw new IllegalArgumentException(\"Expiration must not be null!\");\n            }\n\n            byte[] keyBuf = toByteArray(command.getKey());\n            byte[] valueBuf = toByteArray(command.getValue());\n            \n            Mono<Boolean> m = write(keyBuf, StringCodec.INSTANCE, SETEX, \n                    keyBuf, command.getExpiration().get().getExpirationTimeInSeconds(), valueBuf);\n            return m.map(v -> new BooleanResponse<>(command, v));\n        });\n    }\n\n    private static final RedisCommand<String> PSETEX = new RedisCommand<String>(\"PSETEX\");\n    \n    @Override\n    public Flux<BooleanResponse<SetCommand>> pSetEX(Publisher<SetCommand> commands) {\n        return execute(commands, command -> {\n\n            Assert.notNull(command.getKey(), \"Key must not be null!\");","sourceCodeStart":165,"sourceCodeEnd":201,"githubUrl":"https://github.com/redisson/redisson/blob/91188987c2a9023e7fedabff758681ad9b107f25/redisson-spring/redisson-spring-data/redisson-spring-data-20/src/main/java/org/redisson/spring/data/connection/RedissonReactiveStringCommands.java#L165-L201","documentation":"RedissonReactiveStringCommands.setEX(Publisher<SetCommand>) throws IllegalArgumentException('Expiration must not be null!') when the SetCommand has no expiration. SETEX requires a TTL argument, so the adapter validates that expiration is present before issuing the command.","triggerScenarios":"Calling setEX(...) with SetCommand.set(key, value) (no Expiration) instead of SetCommand.set(key, value, Expiration.seconds(60)).","commonSituations":"Refactoring a set() call site to setEX() and forgetting to add the expiration; configuration code where the TTL parameter is optional and was left null.","solutions":["Always supply an Expiration: SetCommand.set(key, value, Expiration.from(60, TimeUnit.SECONDS)).","If no TTL is wanted, use set(...) rather than setEX(...).","Validate command.getExpiration().isPresent() before submitting to fail with your own clearer error."],"exampleFix":"// before\nSetCommand cmd = SetCommand.set(key, value);\nstringCommands.setEX(Flux.just(cmd)); // throws: Expiration must not be null!\n\n// after\nSetCommand cmd = SetCommand.set(key, value, Expiration.from(60, TimeUnit.SECONDS));\nstringCommands.setEX(Flux.just(cmd));","handlingStrategy":"validation","validationCode":"if (!cmd.getExpiration().isPresent()) {\n    throw new IllegalArgumentException(\"setEX requires an Expiration\");\n}\nstringCommands.setEX(Flux.just(cmd));","typeGuard":"boolean hasExpiration(SetCommand cmd) {\n    return cmd.getExpiration().isPresent();\n}","tryCatchPattern":null,"preventionTips":["setEX always needs Expiration; use set() when no TTL is wanted","Make TTL a required constructor parameter in your own write helpers"],"tags":["redis","redisson","reactive","setex","validation"],"backgroundTag":null,"analyzedSha":"91188987c2a9023e7fedabff758681ad9b107f25","analyzedAt":"2026-08-14T11:39:42.619Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}