{"record":{"id":"708d2fc91c0c5068","repo":"apache/cassandra","slug":"cannot-create-materialized-view-s-for-base-tabl-708d2f","errorCode":null,"errorMessage":"Cannot create materialized view '%s' for base table '%s' as it is being dropped.","messagePattern":"Cannot create materialized view '(.+?)' for base table '(.+?)' as it is being dropped\\.","errorType":"validation","errorClass":"InvalidRequestException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/cql3/statements/schema/CreateViewStatement.java","lineNumber":199,"sourceCode":"        // Guardrail to limit number of mvs per table\n        Iterable<ViewMetadata> tableViews = keyspace.views.forTable(table.id);\n        Guardrails.materializedViewsPerTable.guard(Iterables.size(tableViews) + 1,\n                                                   String.format(\"%s on table %s\", viewName, table.name),\n                                                   false,\n                                                   state);\n\n        if (table.params.gcGraceSeconds == 0)\n        {\n            throw ire(\"Cannot create materialized view '%s' for base table \" +\n                      \"'%s' with gc_grace_seconds of 0, since this value is \" +\n                      \"used to TTL undelivered updates. Setting gc_grace_seconds\" +\n                      \" too low might cause undelivered updates to expire \" +\n                      \"before being replayed.\",\n                      viewName, tableName);\n        }\n\n        if (table.params.pendingDrop)\n            throw ire(\"Cannot create materialized view '%s' for base table \" +\n                      \"'%s' as it is being dropped.\",\n                      viewName, tableName);\n\n        /*\n         * Process SELECT clause\n         */\n\n        Set<ColumnIdentifier> selectedColumns = new HashSet<>();\n\n        if (rawColumns.isEmpty()) // SELECT *\n            table.columns().forEach(c -> selectedColumns.add(c.name));\n\n        rawColumns.forEach(selector ->\n        {\n            if (null != selector.alias)\n                throw ire(\"Cannot use aliases when defining a materialized view (got %s)\", selector);\n\n            if (!(selector.selectable instanceof Selectable.RawIdentifier))","sourceCodeStart":181,"sourceCodeEnd":217,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/cql3/statements/schema/CreateViewStatement.java#L181-L217","documentation":"The statement checks whether the base table is marked pendingDrop in the schema at apply time. If a concurrent DROP TABLE committed between statement preparation and schema application, creating a view against it would produce an orphaned view, so it is rejected.","triggerScenarios":"CREATE MATERIALIZED VIEW racing with DROP TABLE (or ALTER TABLE DROP that triggers a drop) on the same base table; the schema mutation applies after the drop is committed.","commonSituations":"Concurrent schema-change tooling (migration scripts, orchestrators) dropping tables while other sessions create dependent views; race is rare but possible in CI or hot schema-iteration environments.","solutions":["Re-run CREATE MATERIALIZED VIEW after confirming the base table exists and the drop was unintended","If the drop was intentional, skip creating the view and remove it from migration scripts","Serialize schema changes (e.g. run migrations under a schema-agreement guard) to avoid the race"],"exampleFix":"// before\n// DROP TABLE base; (issued concurrently)\nCREATE MATERIALIZED VIEW mv AS SELECT ... FROM base ...;\n// after\n// ensure base table exists and no concurrent DROP is running\nDESCRIBE KEYSPACE keyspace;  -- confirm base table present\nCREATE MATERIALIZED VIEW mv AS SELECT ... FROM base ...;","handlingStrategy":"retry","validationCode":"// check schema agreement before applying\nif (!schemaContainsTable(keyspace, tableName)) throw new IllegalStateException(\"Base table missing; cannot create MV\");","typeGuard":null,"tryCatchPattern":"try { session.execute(createMvStmt); } catch (InvalidQueryException e) { if (e.getMessage().contains(\"being dropped\")) { /* re-check table existence, retry if drop was not intended */ } }","preventionTips":["Serialize schema migrations; avoid concurrent DROP TABLE and CREATE MV on the same table","Use schema-agreement checks in migration tooling before DDL"],"tags":["cql","materialized-view","race-condition","schema-change"],"backgroundTag":"invalid-state-transition","analyzedSha":"88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1","analyzedAt":"2026-09-10T07:29:22.284Z","contentChangedAt":"2026-09-10T07:29:22.284Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}