Skipping Versions
We just downgraded to version 1.15 of admin_toolbar, and now let's pretend we did that when 1.16 was released, because of a breaking change, but now 1.17 is out and the issue we had is fixed. Well, right now, 1.17, won't be installed unless we update the version number manually, once again.
If we knew 1.17 would include the fix (maybe we created a patch), we can mitigate that second manual change because Composer allows you to skip specific versions and then continue with future releases in a couple of ways.
Skipping one Exact Release
The first way to skip a release is to use the "!=" (not equal to) operator.
If we know that there is a breaking change in one version that will be resolved in the next, we can simply skip the broken version with the "!=" (not equal to) operator. I'll demonstrate with Admin Toolbar.
The following command will (at this time) install version 1.16 of Admin Toolbar.
composer require "drupal/admin_toolbar:^1.0 != 1.17"
Basically, what it's saying is "Install admin_toolbar, at least version 1.0, but not 1.17." So, since 1.16 is the latest release that matches those constraints, it is installed.
Now, I'll do the same thing but let's pretend 1.16 had the issue.
composer require "drupal/admin_toolbar:^1.0 != 1.16"
This time, version 1.17 is installed because we wanted at least version 1.0, but not 1.16. And since 1.17 is now out and fixes the issue in 1.16, it is installed.
Now, let's pretend there's an issue with some of our custom code and all versions of the Admin Toolbar module above 1.15. We could continue to add exceptions like this composer require "drupal/admin_toolbar:^1.0 != 1.16 != 1.17"
etc., but that will get unruly pretty quickly. This is an example of where you might want to specify version 1.15 explicitly, but because some project dependencies will require different versions of other dependencies, occasionally, you will want to use a range operator.