diff --git a/src/box/alter.cc b/src/box/alter.cc
index 87f926dd900c41ad3f590a66d297867a67d4e291..a1780983c47abddbb59b700a006d17833e8f7bf2 100644
--- a/src/box/alter.cc
+++ b/src/box/alter.cc
@@ -1898,19 +1898,15 @@ alter_space_move_indexes(struct alter_space *alter, uint32_t begin,
  *
  * @param select Tables from this select to be updated.
  * @param update_value +1 on view creation, -1 on drop.
- * @param suppress_error If true, silently skip nonexistent
- *                       spaces from 'FROM' clause.
- * @param[out] not_found_space Name of a disappeared space.
- * @retval 0 on success, -1 if suppress_error is false and space
- *         from 'FROM' clause doesn't exist.
+ * @retval 0 on success, -1 on error (diag is set).
  */
 static int
-update_view_references(struct Select *select, int update_value,
-		       bool suppress_error, const char **not_found_space)
+update_view_references(struct Select *select, int update_value)
 {
 	assert(update_value == 1 || update_value == -1);
 	struct SrcList *list = sql_select_expand_from_tables(select);
 	int from_tables_count = sql_src_list_entry_count(list);
+	/* Firstly check that everything is correct. */
 	for (int i = 0; i < from_tables_count; ++i) {
 		const char *space_name = sql_src_list_entry_name(list, i);
 		assert(space_name != NULL);
@@ -1926,19 +1922,25 @@ update_view_references(struct Select *select, int update_value,
 			continue;
 		struct space *space = space_by_name(space_name);
 		if (space == NULL) {
-			if (! suppress_error) {
-				assert(not_found_space != NULL);
-				*not_found_space = tt_sprintf("%s", space_name);
-				sqlSrcListDelete(list);
-				return -1;
-			}
-			continue;
+			diag_set(ClientError, ER_NO_SUCH_SPACE, space_name);
+			goto error;
 		}
+	}
+	/* Secondly do the job. */
+	for (int i = 0; i < from_tables_count; ++i) {
+		const char *space_name = sql_src_list_entry_name(list, i);
+		/* See comment before sql_select_constains_cte call above. */
+		if (sql_select_constains_cte(select, space_name))
+			continue;
+		struct space *space = space_by_name(space_name);
 		assert(space->def->view_ref_count > 0 || update_value > 0);
 		space->def->view_ref_count += update_value;
 	}
 	sqlSrcListDelete(list);
 	return 0;
+error:
+	sqlSrcListDelete(list);
+	return -1;
 }
 
 /**
@@ -1964,7 +1966,8 @@ on_create_view_rollback(struct trigger *trigger, void *event)
 {
 	(void) event;
 	struct Select *select = (struct Select *)trigger->data;
-	update_view_references(select, -1, true, NULL);
+	int rc = update_view_references(select, -1);
+	assert(rc == 0); (void)rc;
 	sql_select_delete(select);
 	return 0;
 }
@@ -1993,7 +1996,8 @@ on_drop_view_rollback(struct trigger *trigger, void *event)
 {
 	(void) event;
 	struct Select *select = (struct Select *)trigger->data;
-	update_view_references(select, 1, true, NULL);
+	int rc = update_view_references(select, 1);
+	assert(rc == 0); (void)rc;
 	sql_select_delete(select);
 	return 0;
 }
@@ -2223,19 +2227,8 @@ on_replace_dd_space(struct trigger * /* trigger */, void *event)
 			auto select_guard = make_scoped_guard([=] {
 				sql_select_delete(select);
 			});
-			const char *disappeared_space;
-			if (update_view_references(select, 1, false,
-						   &disappeared_space) != 0) {
-				/*
-				 * Decrement counters which have
-				 * been increased by previous call.
-				 */
-				update_view_references(select, -1, false,
-						       &disappeared_space);
-				diag_set(ClientError, ER_NO_SUCH_SPACE,
-					  disappeared_space);
+			if (update_view_references(select, 1) != 0)
 				return -1;
-			}
 			struct trigger *on_commit_view =
 				txn_alter_trigger_new(on_create_view_commit,
 						      select);
@@ -2337,7 +2330,8 @@ on_replace_dd_space(struct trigger * /* trigger */, void *event)
 			if (on_rollback_view == NULL)
 				return -1;
 			txn_stmt_on_rollback(stmt, on_rollback_view);
-			update_view_references(select, -1, true, NULL);
+			int rc = update_view_references(select, -1);
+			assert(rc == 0); (void)rc;
 			select_guard.is_active = false;
 		}
 	} else { /* UPDATE, REPLACE */
diff --git a/test/sql/view.result b/test/sql/view.result
index d0c3f94a7b6d9c01b33bc9ef564c0e4f83f379f2..6fa8520ba4067e014ef421471cead319ee86d1a5 100644
--- a/test/sql/view.result
+++ b/test/sql/view.result
@@ -271,6 +271,23 @@ box.execute("DROP TABLE c;")
 - null
 - 'Can''t drop space ''C'': other views depend on this space'
 ...
+-- Try to create invalid view using direct insert to space _space.
+space_tuple = box.space._space.index[0]:max():totable()
+---
+...
+space_tuple[1] = space_tuple[1] + 1 -- id
+---
+...
+space_tuple[3] = space_tuple[3] .. '1' -- name
+---
+...
+space_tuple[6].sql = string.gsub(space_tuple[6].sql, 'FROM c', 'FROM ccc')
+---
+...
+box.space._space:insert(space_tuple)
+---
+- error: Space 'CCC' does not exist
+...
 box.space.BCV:drop()
 ---
 ...
diff --git a/test/sql/view.test.lua b/test/sql/view.test.lua
index 2ff7ab3451be7a753473436c92979dbc3be9a2d5..8c370959baacf9e20fd684c02d2ec4b7eccc9437 100644
--- a/test/sql/view.test.lua
+++ b/test/sql/view.test.lua
@@ -101,6 +101,14 @@ box.execute("DROP TABLE c;")
 box.execute("CREATE TABLE c (s1 INT PRIMARY KEY);")
 box.execute("CREATE VIEW bcv(x, y) AS VALUES((SELECT 'k' FROM b), (VALUES((SELECT 1 FROM b WHERE s1 IN (VALUES((SELECT 1 + c.s1 FROM c)))))))")
 box.execute("DROP TABLE c;")
+
+-- Try to create invalid view using direct insert to space _space.
+space_tuple = box.space._space.index[0]:max():totable()
+space_tuple[1] = space_tuple[1] + 1 -- id
+space_tuple[3] = space_tuple[3] .. '1' -- name
+space_tuple[6].sql = string.gsub(space_tuple[6].sql, 'FROM c', 'FROM ccc')
+box.space._space:insert(space_tuple)
+
 box.space.BCV:drop()
 box.execute("DROP TABLE c;")
 box.execute("DROP TABLE b;")