There is something strange going on, and likely unintended behavior relating to state that is supposed to track the content of sqlite_master but does not. I have found two changes to your procedure that "work". One is to simply retry the failing column add statement. The other is to close then reopen the DB before the column add. Both of these suggest that state is changed from what it is just before the initial column add attempt. To me, it is surprising that direct modification of sqlite_master would become a supported operation. In fact, I wonder if it truly is supported. If so, there should perhaps be a pragma, named something like incorporate_direct_schema_modifications.