{"record":{"id":"7a80f06309340711","repo":"flowable/flowable-engine","slug":"token-is-null","errorCode":null,"errorMessage":"token is null","messagePattern":"token is null","errorType":"validation","errorClass":"FlowableIllegalArgumentException","httpStatus":400,"severity":"error","filePath":"modules/flowable-idm-engine/src/main/java/org/flowable/idm/engine/impl/cmd/SaveTokenCmd.java","lineNumber":45,"sourceCode":" * @author Tijs Rademakers\n */\npublic class SaveTokenCmd implements Command<Void>, Serializable {\n\n    private static final long serialVersionUID = 1L;\n    \n    protected IdmEngineConfiguration idmEngineConfiguration;\n    \n    protected Token token;\n\n    public SaveTokenCmd(Token token, IdmEngineConfiguration idmEngineConfiguration) {\n        this.token = token;\n        this.idmEngineConfiguration = idmEngineConfiguration;\n    }\n\n    @Override\n    public Void execute(CommandContext commandContext) {\n        if (token == null) {\n            throw new FlowableIllegalArgumentException(\"token is null\");\n        }\n\n        if (idmEngineConfiguration.getTokenEntityManager().isNewToken(token)) {\n            if (token instanceof TokenEntity) {\n                idmEngineConfiguration.getTokenEntityManager().insert((TokenEntity) token, true);\n            } else {\n                CommandContextUtil.getDbSqlSession(commandContext).insert((Entity) token, idmEngineConfiguration.getIdGenerator());\n            }\n        } else {\n            idmEngineConfiguration.getTokenEntityManager().updateToken(token);\n        }\n\n        return null;\n    }\n}\n","sourceCodeStart":27,"sourceCodeEnd":61,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-idm-engine/src/main/java/org/flowable/idm/engine/impl/cmd/SaveTokenCmd.java#L27-L61","documentation":"SaveTokenCmd persists an authentication Token through the TokenEntityManager (insert for new tokens, update for existing). Since persistence requires an actual Token instance, a null argument is rejected with FlowableIllegalArgumentException.","triggerScenarios":"Calling identityService.saveToken(null) or executing new SaveTokenCmd(config, null); also when a token variable from an earlier lookup/cleanup job is null at save time.","commonSituations":"Custom remember-me / token-store code that loads then saves a token which was already purged; deserialized token objects missing from request payloads.","solutions":["Create the token first (identityService.newToken()) and populate it before saving","Check the code path that produced the null token (lookup already returned nothing)","Null-check before saving and skip or recreate the token accordingly"],"exampleFix":"// before\nidentityService.saveToken(token);\n// after\nif (token == null) {\n    token = identityService.newToken();\n}\nidentityService.saveToken(token);","handlingStrategy":"validation","validationCode":"if (token == null) throw new IllegalArgumentException(\"token must not be null\");","typeGuard":"boolean isSavableToken(Token t) { return t != null && t.getId() != null && !t.getId().trim().isEmpty(); }","tryCatchPattern":"try { identityService.saveToken(token); } catch (FlowableIllegalArgumentException e) { log.error(\"Attempted to save null token\", e); }","preventionTips":["Always create tokens via identityService.newToken() before saving","Re-check token existence after purge/expiry jobs before re-saving","Null-check tokens deserialized from external stores"],"tags":["flowable","idm","null-argument","token"],"backgroundTag":"null-argument","analyzedSha":"d6d39ce1c69ff244f2d9dc6af756a9b95e865586","analyzedAt":"2026-09-11T06:41:19.413Z","contentChangedAt":"2026-09-11T06:41:19.413Z","schemaVersion":2},"datasetVersion":"2026-09-18T11:17:12.947Z"}