That’s it! While I’m testing the tweets use the same text. When I add a nonce it works.
I’m imagining this is to curb spam? Fair enough, but it’s a pain when developing.
At the very least it could give the actual error–that the tweet is rejected due to being a duplicate. This wasted a lot of time. I also notice that the web site gives an error about duplicate tweets, so it’s not like Twitter isn’t clear about this in other cases.