How do i parse products/update webhook to backend server

Topic summary

A developer using Shopify’s Remix App Template is encountering errors when trying to parse webhook data for product updates and send it to a backend server.

The Error:

  • Receiving SyntaxError: Unexpected token 'o', "[object Rea"... is not valid JSON
  • Request.body shows as a ReadableStream that is locked and closed

The Issue:
The developer is attempting to parse the webhook payload using JSON.parse(request.body.toString()), but request.body is a ReadableStream object rather than a string or parsed JSON.

Root Cause:
In modern web APIs (including Remix), request bodies are streams that need to be properly read/consumed before parsing. Calling .toString() on a ReadableStream object doesn’t extract the actual data—it just converts the stream object itself to a string representation like “[object ReadableStream]”.

Solution Needed:
The developer needs to properly consume the stream (e.g., using await request.json() or await request.text()) before attempting to parse or forward the webhook data to their backend server.

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

Hi, I’m using Shopify’s Remix App Template, and have setup a webhook for products updated. I want it to send the updated product to my backend server. However I’m having some issues doing so.

I get this error:

15:42:55 │ remix │ PRODUCTS_UPDATE error: SyntaxError: Unexpected token ‘o’, “[object Rea”… is not valid JSON
and:

Request.body: ReadableStream { locked: true, state: ‘closed’, supportsBYOB: false }

Here is my case for product update:

case 'PRODUCTS_UPDATE':
console.log('PRODUCTS_UPDATE case called.');
    console.log('PRODUCTS_UPDATE called.');
    if ( !request.body ) {
        console.log('PRODUCTS_UPDATE request.body is null.', request.body);
        break
    }
    try {
        const product = JSON.parse(request.body.toString());
        console.log('PRODUCTS_UPDATE product:', product);
        const response = await axios.post(
            `${API_DOMAIN}/products/update`,
            {
                store_url: shop,
                product: product
            },

            {
                headers: {
                    'Content-Type': 'application/json',
                },
            },
        );
    }catch (error: unknown) {
    console.log('PRODUCTS_UPDATE error:', error)
    console.log("Request.body: ______" ,request.body, "______ REQUEST: ______", request, "______");
    }break;