Shopify orders/create returns many 422 errors in remix app

Topic summary

Issue: Frequent HTTP 422 (Unprocessable Entity) errors when handling an orders/create webhook in a Shopify Remix app deployed on Vercel. The errors appear to occur before the webhook is delivered (not reaching the configured destination).

Context:

  • Using latest Remix template with authenticate.webhook(request) in webhooks.jsx.
  • For ORDERS_CREATE, the handler logs payload and then attempts to create/update a REST Webhook (topic: “orders/create”, JSON format) via admin.rest.resources.Webhook.save({ update: true }).
  • Webhook configuration in shopify.server.js declares APP_UNINSTALLED and ORDERS_CREATE with DeliveryMethod.Http and callbackUrl “/webhooks”.
  • Default case returns 404 for unhandled topics; if no admin context, handler throws an empty Response.

Notes:

  • 422 indicates the request is syntactically correct but cannot be processed (validation failure). Author believes failure happens before delivery to the destination URL.
  • Code snippets are central to diagnosing the issue.

Request/Status:

  • Author asks if others see the same problem and for a solution. No resolution or confirmed cause yet; discussion is open.
Summarized with AI on January 2. AI used: gpt-5.

Hello,
I’m using the latest remix template and registered an orders/create webhook. On Vercel I’m getting with this code many 422 errors. These 422 don’t even get send to the webhook destination. It seems like there is something wrong and the error occurs before sending.

Does anyone has the same problem?

Here is my code:

webhooks.jsx

import { authenticate } from "../shopify.server";
import db from "../db.server";

export const action = async ({ request }) => {
  const { topic, shop, session, admin, payload } = await authenticate.webhook(request);

  if (!admin) {
    // The admin context isn't returned if the webhook fired after a shop was uninstalled.
    throw new Response();
  }

  switch (topic) {
    case "APP_UNINSTALLED":
      if (session) {
        await db.session.deleteMany({ where: { shop } });
      }

      break;
    case "ORDERS_CREATE":
      if (session) {
        console.log(payload);
        const webhook = new admin.rest.resources.Webhook({session: session});
        webhook.topic = "orders/create";
        webhook.address = "URL";
        webhook.format = "json";
        webhook.save({
          update: true,
        });
      } 
      break;
      
    case "CUSTOMERS_DATA_REQUEST":
    case "CUSTOMERS_REDACT":
    case "SHOP_REDACT":
    default:
      throw new Response("Unhandled webhook topic", { status: 404 });
  }

  throw new Response();
};

Part of the shopify.server.js code

  webhooks: {
    APP_UNINSTALLED: {
      deliveryMethod: DeliveryMethod.Http,
      callbackUrl: "/webhooks",
    },
    ORDERS_CREATE: {
      deliveryMethod: DeliveryMethod.Http,
      callbackUrl: "/webhooks",
    },
  },

Would be awesome if someone knows the answer!

Best regards

Lukas