turns out there were two issues. the first is as @Carlo1460 described - if you don’t authorise through the app it will silently fail to display or add new OAuth clients.
Secondly, my refresh token had been revoked, and any API calls using this token are returning a 500 (internal server) error, instead of a 401. Probably an unhandled exception bubbling up from somewhere.
authorising through the app and generating a new refresh token solved it for me.
I guess it might be more fair to call this bad UX, than anything actually broken. I’ve reported the misleading http error code from the API to support