{"record":{"id":"871ecb8add1ab27a","repo":"Activiti/Activiti","slug":"couldn-t-operation-db-schema-exceptionsqlsta","errorCode":null,"errorMessage":"couldn't ${operation} db schema: ${exceptionSqlStatement}","messagePattern":"couldn't (.+?) db schema: (.+?)","errorType":"exception","errorClass":"ActivitiException","httpStatus":null,"severity":"error","filePath":"activiti-core/activiti-engine/src/main/java/org/activiti/engine/impl/db/DbSqlSession.java","lineNumber":1286,"sourceCode":"                            log.error(\"problem during schema {}, statement {}\", operation, sqlStatement, e);\n                        } finally {\n                            sqlStatement = null;\n                        }\n                    } else {\n                        sqlStatement = addSqlStatementPiece(sqlStatement, line);\n                    }\n                }\n\n                line = readNextTrimmedLine(reader);\n            }\n\n            if (exception != null) {\n                throw exception;\n            }\n\n            log.debug(\"activiti db schema {} for component {} successful\", operation, component);\n        } catch (Exception e) {\n            throw new ActivitiException(\"couldn't \" + operation + \" db schema: \" + exceptionSqlStatement, e);\n        }\n    }\n\n    /**\n     * MySQL is funny when it comes to timestamps and dates.\n     * <p>\n     * More specifically, for a DDL statement like 'MYCOLUMN timestamp(3)': - MySQL 5.6.4+ has support for timestamps/dates with millisecond (or smaller) precision. The DDL above works and the data in\n     * the table will have millisecond precision - MySQL < 5.5.3 allows the DDL statement, but ignores it. The DDL above works but the data won't have millisecond precision - MySQL 5.5.3 < [version] <\n     * 5.6.4 gives and exception when using the DDL above.\n     * <p>\n     * Also, the 5.5 and 5.6 branches of MySQL are both actively developed and patched.\n     * <p>\n     * Hence, when doing auto-upgrade/creation of the Activiti tables, the default MySQL DDL file is used and all timestamps/datetimes are converted to not use the millisecond precision by string\n     * replacement done in the method below.\n     * <p>\n     * If using the DDL files directly (which is a sane choice in production env.), there is a distinction between MySQL version < 5.6.\n     */\n    protected String updateDdlForMySqlVersionLowerThan56(String ddlStatements) {","sourceCodeStart":1268,"sourceCodeEnd":1304,"githubUrl":"https://github.com/Activiti/Activiti/blob/56435b1a97deeafdc09dd40074b056c89fba5a8a/activiti-core/activiti-engine/src/main/java/org/activiti/engine/impl/db/DbSqlSession.java#L1268-L1304","documentation":"Generic wrapper for failures while executing a schema script (create/drop/upgrade/check) in executeSchemaResource: the SQL statement recorded in exceptionSqlStatement failed, so the whole '<operation> db schema' is aborted with an ActivitiException carrying the failing statement. It signals the database rejected a DDL/DML statement during schema management.","triggerScenarios":"Engine startup with databaseSchemaUpdate=true (or explicit schema create/drop) executes the SQL statements of a schema resource; one statement throws a SQLException, caught by executeSchemaResource's catch block, and 'couldn't <operation> db schema: <sql>' is thrown.","commonSituations":"Tables already exist (partial prior create) causing 'table already exists' on create; insufficient DB user privileges for CREATE TABLE/ALTER; DB type mismatched so dialect-specific SQL fails; reserved keyword or type incompatibilities on unusual DB versions.","solutions":["Read the failing statement in the message and the underlying SQLException cause to see the DB error.","If tables already exist / partial state, either drop the old ACT_* tables or set databaseSchemaUpdate=false and manage schema manually.","Grant the DB user DDL privileges (CREATE, ALTER, DROP) needed by the schema scripts.","Confirm databaseType detection is correct (jdbc url/driver) so the right dialect scripts run.","Run schema scripts manually with your DB tool to get better diagnostics, then start the engine with schema update disabled."],"exampleFix":"// before\nprocessEngineConfiguration.setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE);\n// after (create schema manually via SQL scripts, then)\nprocessEngineConfiguration.setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_FALSE);","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  processEngine = cfg.buildProcessEngine();\n} catch (ActivitiException e) {\n  if (e.getMessage() != null && e.getMessage().startsWith(\"couldn't \") && e.getMessage().contains(\"db schema:\")) {\n    log.error(\"Schema op failed on statement: {} | cause: {}\", e.getMessage(), e.getCause(), e);\n  }\n  throw e;\n}","preventionTips":["Ensure the DB user has CREATE/ALTER/DROP privileges.","Don't point databaseSchemaUpdate=true at a partially created schema; clean or manage schema manually.","Verify databaseType detection matches your actual database.","Execute schema scripts manually with your DB tool for clearer diagnostics."],"tags":["database","schema","sql","ddl"],"backgroundTag":"sql-query-failed","analyzedSha":"56435b1a97deeafdc09dd40074b056c89fba5a8a","analyzedAt":"2026-09-09T21:00:06.703Z","contentChangedAt":"2026-09-09T21:00:06.703Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}