{"record":{"id":"ff6c189e0bbb66cb","repo":"flowable/flowable-engine","slug":"process-definition-version-must-be-a-positive-numb","errorCode":null,"errorMessage":"Process definition version must be a positive number","messagePattern":"Process definition version must be a positive number","errorType":"validation","errorClass":"FlowableException","httpStatus":null,"severity":"error","filePath":"modules/flowable-engine/src/main/java/org/flowable/engine/impl/migration/ProcessInstanceMigrationDocumentBuilderImpl.java","lineNumber":156,"sourceCode":"        this.processInstanceVariables.put(variableName, variableValue);\n        return this;\n    }\n\n    @Override\n    public ProcessInstanceMigrationDocumentBuilder addProcessInstanceVariables(Map<String, Object> processInstanceVariables) {\n        this.processInstanceVariables.putAll(processInstanceVariables);\n        return this;\n    }\n\n    @Override\n    public ProcessInstanceMigrationDocument build() {\n\n        if (migrateToProcessDefinitionId == null) {\n            if (migrateToProcessDefinitionKey == null) {\n                throw new FlowableException(\"Process definition key cannot be null\");\n            }\n            if (migrateToProcessDefinitionVersion != null && migrateToProcessDefinitionVersion < 0) {\n                throw new FlowableException(\"Process definition version must be a positive number\");\n            }\n        }\n\n        ProcessInstanceMigrationDocumentImpl document = new ProcessInstanceMigrationDocumentImpl();\n        document.setProcessInstanceIdsToMigrate(processInstanceIdsToMigrate);\n        document.setMigrateToProcessDefinitionId(migrateToProcessDefinitionId);\n        document.setMigrateToProcessDefinition(migrateToProcessDefinitionKey, migrateToProcessDefinitionVersion, migrateToProcessDefinitionTenantId);\n        if (preUpgradeScript != null) {\n            document.setPreUpgradeScript(preUpgradeScript);\n        }\n        if (preUpgradeJavaDelegate != null) {\n            document.setPreUpgradeJavaDelegate(preUpgradeJavaDelegate);\n        }\n        if (preUpgradeJavaDelegateExpression != null) {\n            document.setPreUpgradeJavaDelegateExpression(preUpgradeJavaDelegateExpression);\n        }\n        if (postUpgradeScript != null) {\n            document.setPostUpgradeScript(postUpgradeScript);","sourceCodeStart":138,"sourceCodeEnd":174,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-engine/src/main/java/org/flowable/engine/impl/migration/ProcessInstanceMigrationDocumentBuilderImpl.java#L138-L174","documentation":"When no target process definition ID is set, build() validates that the optional migrateToProcessDefinitionVersion is a positive number. A negative version value is invalid because process definition versions start at 1, so build() throws this FlowableException.","triggerScenarios":"Calling build() with migrateToProcessDefinitionId null and migrateToProcessDefinitionVersion set to a negative number, typically via migrateToProcessDefinition(version, key) or a JSON document with a negative version field.","commonSituations":"Passing a sentinel value like -1 for 'latest version'; parsing a version from config/JSON that was never sanitized; off-by-one or unsigned/signed confusion when computing versions.","solutions":["Pass a positive version number (>= 1) to migrateToProcessDefinition(version, key)","Use 1 or omit the version (migrateToProcessDefinitionKey) if you intend the first/latest version","Validate or sanitize the version value before building the document"],"exampleFix":"// before\nbuilder.migrateToProcessDefinition(-1, \"orderProcess\");\n// after\nint version = Math.max(1, configuredVersion);\nbuilder.migrateToProcessDefinition(version, \"orderProcess\");","handlingStrategy":"validation","validationCode":"if (targetVersion != null && targetVersion < 1) {\n    throw new IllegalArgumentException(\"Process definition version must be >= 1\");\n}","typeGuard":"boolean isValidVersion(Integer v) { return v == null || v >= 1; }","tryCatchPattern":"try {\n    document = builder.build();\n} catch (FlowableException e) {\n    if (e.getMessage().contains(\"must be a positive number\")) {\n        builder.migrateToProcessDefinitionKey(key); // drop invalid version\n        document = builder.build();\n    } else { throw e; }\n}","preventionTips":["Never use negative sentinels like -1 for 'latest version'","Clamp or sanitize versions parsed from JSON/config","Remember Flowable versions start at 1"],"tags":["flowable","process-migration","validation","negative-value"],"backgroundTag":"value-out-of-range","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"}