The shell does not somehow "magically know" that there is a table with the name specified. When SQLite3 starts it loads (parses) the data dictionary (sqlite_master) into internal structures that represent the schema. This dictionary contains (at present) 3 "branches". There is a branch that links all the indexes. There is a branch that links all triggers. There is a branch that links all the table-like objects (tables, views, virtual tables, and so on and so forth -- all the things which one may use as the target of FROM in SELECT ... FROM). As you can see, this is quite an efficient way of classifying objects. It does not matter whether a thing is a table or a view or a virtual table. What matters is that is if something that can be used as the target of a SELECT FROM -- that is behaves as if it were a table. (A view is nothing more than an ephemeral table). When you command "DROP VIEW name" SQLlite3 searches the structure that contains table like objects looking for the name you specified. If the name is a view, then it is dropped. However, if it is not the type of thing you asked for an error is raised. On the other hand, if you command "DROP INDEX name" then only the structures containing the list of indexes are searched. If the name is not found then an error is raised. It does not go on a hunt looking for what you might have meant. It is your job to command what you mean. However, in the case of table-like objects which may be the target of SELECT FROM, you may issue a command naming the wrong object type, in which case you get informed of **YOUR** error.