{"record":{"id":"ba6c2cb5aee594f9","repo":"flowable/flowable-engine","slug":"the-target-tenant-id-must-not-be-null","errorCode":null,"errorMessage":"The target tenant id must not be null.","messagePattern":"The target tenant id must not be null\\.","errorType":"validation","errorClass":"FlowableIllegalArgumentException","httpStatus":null,"severity":"error","filePath":"modules/flowable-engine-common/src/main/java/org/flowable/common/engine/impl/tenant/ChangeTenantIdBuilderImpl.java","lineNumber":35,"sourceCode":"import org.flowable.common.engine.api.tenant.ChangeTenantIdResult;\n\n/**\n * @author Filip Hrisafov\n */\npublic class ChangeTenantIdBuilderImpl implements ChangeTenantIdBuilder {\n\n    protected final String sourceTenantId;\n    protected final String targetTenantId;\n    protected final ChangeTenantIdManager changeTenantIdManager;\n\n    protected String definitionTenantId;\n\n    public ChangeTenantIdBuilderImpl(String sourceTenantId, String targetTenantId, ChangeTenantIdManager changeTenantIdManager) {\n        if (sourceTenantId == null) {\n            throw new FlowableIllegalArgumentException(\"The source tenant id must not be null.\");\n        }\n        if (targetTenantId == null) {\n            throw new FlowableIllegalArgumentException(\"The target tenant id must not be null.\");\n        }\n        this.sourceTenantId = sourceTenantId;\n        this.targetTenantId = targetTenantId;\n        if (sourceTenantId.equals(targetTenantId)) {\n            throw new FlowableIllegalArgumentException(\"The source and the target tenant ids must be different.\");\n        }\n        this.changeTenantIdManager = changeTenantIdManager;\n    }\n\n    @Override\n    public ChangeTenantIdBuilder definitionTenantId(String definitionTenantId) {\n        if (definitionTenantId == null) {\n            throw new FlowableIllegalArgumentException(\"definitionTenantId must not be null\");\n        }\n        this.definitionTenantId = definitionTenantId;\n        return this;\n    }\n","sourceCodeStart":17,"sourceCodeEnd":53,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-engine-common/src/main/java/org/flowable/common/engine/impl/tenant/ChangeTenantIdBuilderImpl.java#L17-L53","documentation":"Flowable throws FlowableIllegalArgumentException when constructing a ChangeTenantIdBuilderImpl with a null targetTenantId. The builder moves data between tenants, so both source and target tenant ids must be valid strings. This is an eager constructor argument validation to fail fast before any data operations.","triggerScenarios":"Calling ProcessEngineManagementService (or engine-specific) changeTenantId(sourceTenantId, null), or passing a null variable that flows into the new ChangeTenantIdBuilderImpl(source, target, manager) constructor.","commonSituations":"Tenant id read from config or request parameter that is null/missing; dynamically resolved tenant id not set in a multi-tenant deployment.","solutions":["Ensure the target tenant id string is non-null before calling changeTenantId(source, target)","Check that the config/property/request parameter supplying the target tenant is actually populated","Validate inputs at the application boundary and reject the operation early with a clear message"],"exampleFix":"// before\nmanagementService.changeTenantId(\"tenantA\", targetTenant);\n// after\nif (targetTenant == null) throw new IllegalArgumentException(\"targetTenant is required\");\nmanagementService.changeTenantId(\"tenantA\", targetTenant);","handlingStrategy":"validation","validationCode":"if (sourceTenantId == null || targetTenantId == null) {\n    throw new IllegalArgumentException(\"source and target tenant ids are required\");\n}","typeGuard":"boolean hasTenantIds(String s, String t) {\n    return s != null && !s.trim().isEmpty() && t != null && !t.trim().isEmpty();\n}","tryCatchPattern":"try {\n    managementService.changeTenantId(sourceTenantId, targetTenantId);\n} catch (FlowableIllegalArgumentException e) {\n    logger.error(\"Invalid tenant change request: {}\", e.getMessage());\n}","preventionTips":["Validate tenant ids at the API/config boundary before calling the engine","Fail fast on missing tenant configuration at startup","Log tenant ids passed to migrations for traceability"],"tags":["flowable","null-check","tenant","argument-validation"],"backgroundTag":"null-argument","analyzedSha":"d6d39ce1c69ff244f2d9dc6af756a9b95e865586","analyzedAt":"2026-09-11T06:41:19.413Z","contentChangedAt":"2026-09-11T06:41:19.413Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}