{"record":{"id":"e6186ef5c66fd042","repo":"vitessio/vitess","slug":"direct-ddl-is-disabled","errorCode":null,"errorMessage":"direct DDL is disabled","messagePattern":"direct DDL is disabled","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"go/vt/schema/online_ddl.go","lineNumber":51,"sourceCode":"\nvar (\n\tonlineDdlUUIDRegexp               = regexp.MustCompile(`^[0-f]{8}_[0-f]{4}_[0-f]{4}_[0-f]{4}_[0-f]{12}$`)\n\tonlineDDLGeneratedTableNameRegexp = regexp.MustCompile(`^_[0-f]{8}_[0-f]{4}_[0-f]{4}_[0-f]{4}_[0-f]{12}_([0-9]{14})_(gho|ghc|del|new|vrepl)$`)\n\tptOSCGeneratedTableNameRegexp     = regexp.MustCompile(`^_.*_old$`)\n\tmigrationContextValidatorRegexp   = regexp.MustCompile(`^[\\w:-]*$`)\n)\n\nvar onlineDDLInternalTableHintsMap = map[string]bool{\n\t\"vrp\": true, // vreplication\n\t\"gho\": true, // gh-ost\n\t\"ghc\": true, // gh-ost\n\t\"del\": true, // gh-ost\n\t\"new\": true, // pt-osc\n}\n\nvar (\n\t// ErrDirectDDLDisabled is returned when direct DDL is disabled, and a user attempts to run a DDL statement\n\tErrDirectDDLDisabled = errors.New(\"direct DDL is disabled\")\n\t// ErrOnlineDDLDisabled is returned when online DDL is disabled, and a user attempts to run an online DDL operation (submit, review, control)\n\tErrOnlineDDLDisabled = errors.New(\"online DDL is disabled\")\n\t// ErrForeignKeyFound indicates any finding of FOREIGN KEY clause in a DDL statement\n\tErrForeignKeyFound = errors.New(\"Foreign key found\")\n\t// ErrRenameTableFound indicates finding of ALTER TABLE...RENAME in ddl statement\n\tErrRenameTableFound = errors.New(\"RENAME clause found\")\n)\n\nconst (\n\tSchemaMigrationsTableName = \"schema_migrations\"\n\tRevertActionStr           = \"revert\"\n)\n\n// ValidateMigrationContext validates that the given migration context only uses valid characters\nfunc ValidateMigrationContext(migrationContext string) error {\n\tif migrationContextValidatorRegexp.MatchString(migrationContext) {\n\t\treturn nil\n\t}","sourceCodeStart":33,"sourceCodeEnd":69,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/vt/schema/online_ddl.go#L33-L69","documentation":"ErrDirectDDLDisabled is a sentinel error returned by TryExecute when a direct (in-place) DDL statement is attempted while direct DDL is disabled in the tablet's online-DDL configuration. It forces users to route schema changes through online DDL (gh-ost/pt-osc) or explicitly re-enable direct DDL.","triggerScenarios":"Submitting a plain DDL statement (ALTER/CREATE/DROP without an online-DDL prefix) to the vttablet ExecuteApiPath / query service with -ddl_strategy set such that direct DDL is disallowed (e.g. ddl_strategy='online' or empty direct allowance).","commonSituations":"Environments where operators disabled direct DDL to protect production (long ALTERs locking tables); CI clusters configured for online-DDL only; users unaware that ddl_strategy governs direct vs online execution.","solutions":["Use an online DDL strategy: prefix the statement with a comment like /*vt+ ddl_strategy=gh-ost */ or set -ddl_strategy appropriately","Change the tablet's ddl_strategy flag to allow direct DDL (e.g. 'direct') if acceptable for the operation","Route the change through vtctldclient ApplySchema for coordinated application","Check errors.Is(err, schema.ErrDirectDDLDisabled) in tooling to present a friendly message"],"exampleFix":"-- before\nALTER TABLE t ADD COLUMN c INT;\n-- after\nALTER /*vt+ ddl_strategy=gh-ost */ TABLE t ADD COLUMN c INT;","handlingStrategy":"validation","validationCode":"strategy := viper.GetString(\"ddl_strategy\")\nif !strings.Contains(strategy, \"direct\") && isDirectDDL(stmt) {\n    return fmt.Errorf(\"rewrite %s with ddl_strategy=online or enable direct DDL\", stmt)\n}","typeGuard":null,"tryCatchPattern":"_, err := tm.TryExecute(ctx, stmt)\nif errors.Is(err, schema.ErrDirectDDLDisabled) {\n    // fall back to online DDL strategy or surface config guidance\n}","preventionTips":["Embed an explicit /*vt+ ddl_strategy=... */ comment in all migrations","Keep a keyspace-level policy for which strategies are permitted","Test migrations in CI with the same ddl_strategy as production","Educate tooling authors that direct DDL may be disabled by policy"],"tags":["ddl","online-ddl","configuration","mysql"],"backgroundTag":"ddl-strategy-disabled","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}