View Categories

Troubleshooting REST API Errors

4 min read

Fix 404, 403, 500, JSON, and CORS issues when using REST inside custom or add-on commands.

If your custom command or add-on uses:

fetch('/wp-json/...')

and the terminal prints errors or nothing happens, the issue often comes from REST API configuration, routing, permission callbacks, or caching.

This guide helps diagnose and fix every common REST issue.


🔹 1. Check REST Endpoint in the Browser First #

Before testing inside the terminal, open the URL directly:

Example:

https://yoursite.com/wp-json/myaddon/v1/data

If you see:

  • valid JSON → good
  • an error message → route exists but failing
  • {"code":"rest_no_route"} → route doesn’t exist
  • white screen → fatal PHP error

🔹 2. 404: Route Not Registered #

Most common error:

{"code":"rest_no_route", "message":"No route was found"}

Causes:

  • wrong namespace
  • wrong route path
  • missing endpoint
  • callback not loaded
  • plugin inactive

Correct registration example:

register_rest_route('myaddon/v1', '/data', [
    'methods'  => 'GET',
    'callback' => 'myaddon_get_data',
    'permission_callback' => '__return_true'
]);

Common mistakes:

❌ declaring route inside a function that never runs
❌ wrong namespace (myaddon vs my-add-on)
❌ using /myaddon/v1/data instead of namespace + route


🔹 3. 403: Permission Callback Blocking Access #

If you get:

{"code":"rest_forbidden", "message":"Sorry, you are not allowed."}

Your permission_callback is the problem.

Fix (for public endpoints):

'permission_callback' => '__return_true'

Fix (for logged-in users only):

'permission_callback' => function() {
    return is_user_logged_in();
}

Fix (admin-only):

'permission_callback' => function() {
    return current_user_can('manage_options');
}

🔹 4. 500: PHP Fatal Error Inside the Callback #

Console shows:

Failed to load resource: the server responded with a status of 500

To diagnose:

  1. Enable WP debug: define('WP_DEBUG', true); define('WP_DEBUG_LOG', true);
  2. Re-run the request
  3. Check: /wp-content/debug.log

Common causes:

  • undefined variables
  • undefined functions
  • wrong return type
  • missing wp_send_json()
  • database errors

Correct callback example:

function myaddon_get_data() {
    return [
        'success' => true,
        'items' => [1,2,3]
    ];
}

🔹 5. Browser Says “Unexpected token <” or Red Error in Console #

This means your endpoint is returning HTML, not JSON.

Cause examples:

  • Fatal error before JSON output
  • Theme printing HTML
  • Security plugin printing warnings
  • A plugin redirecting the request

Check the response in Network → Preview.

If you see:

<html>...

Something is injecting HTML into your response.

Fix:

  • disable security plugins temporarily
  • ensure no echo or print_r in callback
  • disable maintenance mode plugins

🔹 6. Wrong HTTP Method (GET vs POST) #

Your route may define:

'methods' => 'POST'

But your JS uses:

fetch('/wp-json/myaddon/v1/data')

→ Default fetch is GET → mismatch → fails.

Solution:

Match the method:

fetch('/wp-json/myaddon/v1/data', {
    method: 'POST',
    body: JSON.stringify({...}),
    headers: { 'Content-Type': 'application/json' }
});

OR change the route to:

'methods' => 'GET'

🔹 7. Nonce Required (For Authenticated Requests) #

If your endpoint requires the user to be logged in, you must include a nonce:

wp_localize_script('my-addon', 'MyAddOnData', [
    'nonce' => wp_create_nonce('wp_rest')
]);

JavaScript:

fetch('/wp-json/myaddon/v1/secure', {
    headers: {
        'X-WP-Nonce': MyAddOnData.nonce
    }
});

Otherwise you’ll get:

403 forbidden (missing nonce)

🔹 8. CORS Errors (When Calling External APIs) #

If your JS calls external services like:

https://api.blockchain.com/
https://some-other-site.com/

And the browser shows:

CORS policy error

This cannot be fixed from the terminal plugin.

Options:

  • Use a server-side proxy REST route
  • Contact the API provider to enable CORS
  • Use a WordPress-side wp_remote_get()

Example proxy:

function myaddon_proxy() {
    $res = wp_remote_get('https://external-api.com/data');
    return json_decode(wp_remote_retrieve_body($res), true);
}

🔹 9. JSON Parse Errors #

If the terminal prints:

Unexpected end of JSON input

or:

Invalid JSON response

Your endpoint is outputting:

  • blank output
  • whitespace
  • BOM encoding
  • HTML warnings
  • PHP notices

Check response in Network → Response.

Fix:

  • ensure callback returns pure array
  • no echoes
  • no HTML
  • no error messages

🔹 10. REST Conflicts With Security Plugins #

Plugins like:

  • Wordfence
  • Defender
  • Sucuri
  • Ninja Firewall
  • iThemes Security

…may block custom REST routes.

Fix:

  • whitelist URIs under the plugin’s firewall settings
  • disable “block REST API for guests”
  • disable “REST API hardening” temporarily

🔹 11. REST Blocked by Caching Plugins #

Page caching plugins may:

  • cache REST responses
  • merge JS that performs requests
  • block REST for anonymous visitors
  • rewrite URLs
  • break authentication

Fix:

  • Exclude /wp-json/ from cache
  • Disable REST API caching (if plugin has it)
  • Turn off JS combine/minify for add-on scripts

🎯 Summary #

REST issues usually fall into one of these categories:

✔ 404 → route not registered #

✔ 403 → invalid permission callback or missing nonce #

✔ 500 → PHP error inside callback #

✔ HTML returned instead of JSON #

✔ JS calling wrong method (GET/POST mismatch) #

✔ CORS error from external APIs #

✔ response corrupted by notices/echo/debug output #

✔ security plugin blocking endpoint #

✔ caching plugin interfering #

Once the route loads properly and the callback returns clean JSON, commands perform reliably.

Leave a Reply

Your email address will not be published. Required fields are marked *