HeyPuter/puter · error · HttpError

bad_request

bad_request

Error message

Missing or invalid `site_uuid`

What it means

The `POST /delete-site` endpoint requires a `site_uuid` string in the JSON request body. The controller validates the field immediately and rejects with HTTP 400 if it is missing, not a string, or empty. This is a client-side input error — the request never reaches the store layer.

Source

Thrown at src/backend/controllers/hosting/HostingController.js:69

                allowFullAccessToken: true,
                requireVerified: true,
                // Destructive, and pairs with the `subdomains:create`
                // budget on the driver side.
                rateLimit: {
                    scope: 'delete-site',
                    limit: 60,
                    window: 60_000,
                    key: 'user',
                    bySubscription: {
                        [DEFAULT_FREE_SUBSCRIPTION]: 30,
                        [DEFAULT_TEMP_SUBSCRIPTION]: 10,
                    },
                },
            },
            async (req, res) => {
                const { site_uuid } = req.body ?? {};
                if (!site_uuid || typeof site_uuid !== 'string') {
                    throw new HttpError(400, 'Missing or invalid `site_uuid`', {
                        legacyCode: 'bad_request',
                    });
                }

                const row = await this.subdomainStore.getByUuid(site_uuid, {
                    userId: req.actor.user.id,
                });
                if (!row) {
                    throw new HttpError(
                        404,
                        'Site not found or not owned by you',
                        { legacyCode: 'not_found' },
                    );
                }
                if (row.protected) {
                    throw new HttpError(
                        403,
                        'Cannot delete a protected subdomain',

View on GitHub (pinned to 908ec23eda)

Solutions

  1. Ensure the request body is valid JSON with a `site_uuid` field set to the site's UUID string.
  2. Set the `Content-Type: application/json` header so Express parses the body.
  3. Confirm the UUID comes from a prior list-sites or create-site response, not a fabricated value.
  4. Add a client-side check that `site_uuid` is a non-empty string before posting.

Example fix

// before
await fetch('/api/delete-site', {
  method: 'POST',
  body: JSON.stringify({ uuid: site.id }), // wrong field name
});

// after
await fetch('/api/delete-site', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ site_uuid: site.uuid }),
});
Defensive patterns

Strategy: validation

Validate before calling

function isValidSiteUuid(v) {
  return typeof v === 'string' && v.length > 0;
}

// before calling
if (!isValidSiteUuid(site.uuid)) {
  throw new Error('Cannot delete: site UUID is missing');
}
await fetch('/api/delete-site', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ site_uuid: site.uuid }),
});

Type guard

/** @param {unknown} v @returns {v is string} */
function isNonEmptyString(v) {
  return typeof v === 'string' && v.length > 0;
}

Try / catch

try {
  const res = await fetch('/api/delete-site', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ site_uuid }),
  });
  if (!res.ok) throw await res.json();
} catch (e) {
  if (e.code === 'bad_request') {
    console.error('site_uuid is missing or invalid:', e.message);
  }
}

Prevention

When it happens

Trigger: Calling `POST /api/delete-site` with a body that omits `site_uuid`, passes a number/object/null, or passes an empty string. Also fires if the body is not parsed as JSON (wrong Content-Type) so `req.body` is undefined.

Common situations: Frontend sends the UUID from the wrong field name (e.g., `uuid` instead of `site_uuid`); the value is undefined because the site list row was null; a test harness posts an incomplete fixture.

Related errors


AI-assisted analysis of HeyPuter/puter@908ec23eda (2026-08-12). Data as JSON: /api/errors/05a457632ad1a79b. Report an issue: GitHub.