processWebhooks(): Failed to process webhook: Error: No body was received when processing webhook

Topic summary

Developers encounter an error when processing Shopify webhooks: “No body was received when processing webhook.” The issue occurs despite the webhook payload being present in the request.

Root Cause:
The express.json() middleware parses the request body into JSON before the Shopify webhook handler receives it. However, Shopify’s processWebhooks() function expects the raw body string, causing the processing to fail.

Solutions Provided:

  1. Middleware Order (Simplest): Place the webhook route before app.use(express.json()) in index.js. This prevents body parsing from interfering with webhook processing.

  2. Raw Body Preservation (Alternative): Implement a custom body parser that saves a raw copy of the body to req.rawBody, then swap the parsed body back to raw before the webhook handler executes.

Implementation:
Multiple users confirmed that reordering middleware—ensuring shopify.processWebhooks() runs before express.json()—resolves the error. This applies to both the standard Shopify CLI-generated code and custom implementations using body-parser.

Summarized with AI on November 16. AI used: claude-sonnet-4-5-20250929.

I have a custom app that I started w/ the tutorial. I did not touch anything in the webhook handling code, it looks like this in web/index.js:

import webhookHandlers from "./webhook-handlers.js";
...

const app = express();
...
app.post(
  shopify.config.webhooks.path,
  // -ignore
  shopify.processWebhooks({ webhookHandlers: webhookHandlers })
);

I have not edit’d the webhook-handlers.js file either, it starts out like this:

export default {
  PRODUCTS_UPDATE: {
    deliveryMethod: DeliveryMethod.Http,
    callbackUrl: "/api/webhooks",
    callback: async (topic, shop, body, webhookId) => {
      console.log('--- Product update ---');
      const payload = JSON.parse(body);
      console.log(payload);
      console.log('--- /Product update ---');
    },
  },
...

I wanted to test this out, so I went to Admin Settings->Notifications and added Product Update webhook as follows:

And then I click on the ‘Send test notification’

dumbo82_1-1678992870348.png

In my app, it receives the notification, but the processWebhooks() gives me this error even though I do see a body:

2023-03-16 18:44:56 | backend  | [shopify-api/INFO] Processing webhook request | {apiVersion: , domain: , topic: , webhookId: }
2023-03-16 18:44:56 | backend  | [shopify-app/ERROR] Failed to process webhook: Error: No body was received when processing webhook

To debug, I log the full request to console and i did see it come back w/ a body portion:

2023-03-16 18:57:38 | backend | body: {> 2023-03-16 18:57:38 | backend | id: 788032119674292900,> 2023-03-16 18:57:38 | backend | title: ‘Example T-Shirt’,> 2023-03-16 18:57:38 | backend | body_html: ‘An example T-Shirt’,> 2023-03-16 18:57:38 | backend | vendor: ‘Acme’,> 2023-03-16 18:57:38 | backend | product_type: ‘Shirts’,> 2023-03-16 18:57:38 | backend | created_at: null,> 2023-03-16 18:57:38 | backend | handle: ‘example-t-shirt’,> 2023-03-16 18:57:38 | backend | updated_at: ‘2023-03-16T14:57:38-04:00’,> 2023-03-16 18:57:38 | backend | published_at: ‘2023-03-16T14:57:38-04:00’,> 2023-03-16 18:57:38 | backend | template_suffix: null,> 2023-03-16 18:57:38 | backend | status: ‘active’,> …> 2023-03-16 18:57:38 | backend | images: [ [Object] ],> 2023-03-16 18:57:38 | backend | image: null> 2023-03-16 18:57:38 | backend | },> 2023-03-16 18:57:38 | backend | _body: true,

1 Like

Hey,

I figured it out.

Add the following to your main index.js

const bodyParserPrewiring = (server) => {
  // save a raw (unprocessed) version of 'body' to 'rawBody'
  function parseVerify(req, res, buf, encoding) {
    if (buf && buf.length) {
      req.rawBody = buf.toString(encoding || 'utf8')
    }
  }

  server.use(bodyParser.json({
    verify: parseVerify,
    limit: '10mb'
  }));

  server.use(bodyParser.urlencoded({
    extended: true,
    verify: parseVerify,
    limit: '10mb'
  }));
}

const app = express();
bodyParserPrewiring(app)
// for webhooks, convert the parsed body back to raw body
app.post("/api/webhooks", function(req, res, next) {
  req.body = req.rawBody
  next(); // go on to the real webhook handler
});

What’s happening, and I don’t know why, is req.body is being processed into JSON, the shopify webhook handler expects the original raw string and so it fails.

So the fix is, before anything else, save a raw copy of the body, and then before your webhook handler, swap out the JSON body with the raw body.

1 Like

You need to make sure that this snippet:

app.post(
  shopify.config.webhooks.path,
  // -ignore
  shopify.processWebhooks({ webhookHandlers: webhookHandlers })
);

is before the expression.json() middleware:

app.use(express.json());

Like this:

const app = express();

app.post(
  shopify.config.webhooks.path,
  // -ignore
  shopify.processWebhooks({ webhookHandlers: webhookHandlers })
);

app.use(express.json());
3 Likes

That was it for me. Make sure to append

app.use(bodyParser.json());after the Shopify CLI code

thanks worked for me too, putting shopify.process before app.use(express.json())

1 Like