I wish that would be the problem, but unfortunately it isn't. There are indeed four placeholders and I'm passing three to execute, but that's just because I edited the code to post it here and missed that. The number of arguments I'm passing in the actual code is correct.
I also have RaiseError active. The INSERT statement definitely works, as later on I can see the row is in the database. It's just that the entry I'm inserting in the other table using the last_insert_id() has the wrong id.