true` and no `rest_base`, and it came * back as "not available via REST API" from an ability whose whole job was * to read it. * * A `post_tags => post_tag` alias used to live here too, quietly accepting * a slug that is not a taxonomy on any site. It is gone on purpose. A tool * is reachable only through what it advertises, and quietly accepting a * second spelling makes the advertised contract false: the next caller * guesses `tags`, then `posttag`, and there is no version of that list that * ends. The refusals below name the taxonomy and point at * `find-taxonomies`, so a wrong guess costs one round trip and teaches the * right slug. * * @param string $taxonomy Taxonomy slug. * * @return string|WP_Error Route with a leading slash, or an error naming the taxonomy. * @since 1.4.0 */ private function get_taxonomy_route( string $taxonomy ): string|WP_Error { // Core returns '' for both "no such taxonomy" and "not in the REST API", // and the caller can act on one but not the other, so they are separated // here before core is asked. if ( ! get_taxonomy( $taxonomy ) ) { return new WP_Error( 'invalid_taxonomy', sprintf( /* translators: 1: taxonomy slug that was requested, 2: the ability to call instead. */ __( 'No taxonomy named "%1$s" is registered on this site. Use %2$s to list the ones that are.', 'albert-ai-butler' ), $taxonomy, 'albert/find-taxonomies' ), [ 'status' => 404 ] ); } $route = rest_get_route_for_taxonomy_items( $taxonomy ); if ( $route === '' ) { return new WP_Error( 'taxonomy_not_rest_enabled', sprintf( /* translators: %s: taxonomy slug that was requested. */ __( 'The "%s" taxonomy is registered on this site but is not exposed over the REST API, so Albert cannot read or change its terms.', 'albert-ai-butler' ), $taxonomy ), [ 'status' => 400 ] ); } return $route; } }