Specifically Firefox appears to throw before the onsuccess event is fired on the IDBRequest returned from .open. IE however allows it to be called as soon as the oncomplete event is fired on the VERSION_CHANGE transaction.
The IE behavior seems like the better one to me.
Currently transaction() doesn't appear to throw due to being called "too early" in the spec at all.
Section 3.1.7 now reads in part as follows (see last sentence for change):
A VERSION_CHANGE transaction can never run concurrently with other transactions. When a VERSION_CHANGE transaction is created, the implementation must wait to start the VERSION_CHANGE transaction until no other transactions against the same database are running. As long as the VERSION_CHANGE transaction is pending, the implementation must wait before starting any other transactions against the same database until the VERSION_CHANGE transaction is finished. However, a new transaction MAY be started as soon as the oncomplete handler is invoked.
Live as of Editor's draft Feb 29.
Actually, the added language only stated when transactions should run. It didn't say anything about when scheduling transactions should throw. And the spec still had text in the IDBDatabase.transaction definition that said that we should throw until the "success" event for the open call was fired.
I've fixed this to make it more clear that scheduling transactions is always allowed once the versionchange transaction is committed.