I had the same problem. Something I noticed that will be useful for others with the same problem:
Every time you run a migration, the name of your javascript/typescript migration file (e.g. 2023.05.25T14.49.35.create-and-populate-state-table.js) is stored in the database so that strapi knows not the run that file again.
TLDR: Make sure you rename your migration file or create a new one for new changes as strapi doesn’t rerun them.
For the strapi team: would it be worth storing in the strapi_migrations table the migration file’s checksum (e.g. sha, md5, etc) as well? #foodForThought