WP_Query orderby breaks when using AJAX?

I believe Milo is right, it’s probably a filter affecting this. Ajax requests look like admin requests (that is, is_admin() returns true), so it’s possible that something is checking if is_admin() and adding the filter in those cases.

You can set 'suppress_filters' => true in your args array and it will probably work. Note that doing so can prevent a query from being cached, or prevent plugins from doing what they need to with a query. It’s possible that this may not affect you, but still something to keep in mind.