HeyPuter/puter · warning · HttpError

bad_request

bad_request

Error message

`url` must be a string or null

What it means

Thrown by POST /set-desktop-bg (DesktopController) when the request includes a `url` field whose value is neither a string nor null. The handler builds a preference patch object and only accepts string|null for url; undefined means 'leave unchanged', any other type (number, boolean, object, array) is rejected with legacy `bad_request`. Passing null explicitly clears the wallpaper URL.

Source

Thrown at src/backend/controllers/desktop/DesktopController.js:77

    registerRoutes(router) {
        // -- Desktop background --------------------------------------

        router.post(
            '/set-desktop-bg',
            {
                subdomain: 'api',
                requireUserActor: true,
                allowFullAccessToken: true,
                rateLimit: PREFERENCE_WRITE_LIMIT,
            },
            async (req, res) => {
                const { url, color, fit } = req.body ?? {};

                const patch = {};
                if (url !== undefined) {
                    if (url !== null && typeof url !== 'string') {
                        throw new HttpError(
                            400,
                            '`url` must be a string or null',
                            { legacyCode: 'bad_request' },
                        );
                    }
                    patch.desktop_bg_url = url;
                }
                if (color !== undefined) {
                    if (color !== null && typeof color !== 'string') {
                        throw new HttpError(
                            400,
                            '`color` must be a string or null',
                            { legacyCode: 'bad_request' },
                        );
                    }
                    patch.desktop_bg_color = color;
                }
                if (fit !== undefined) {

View on GitHub (pinned to 908ec23eda)

Solutions

  1. Send `url` as a string URL, or as null to clear it, or omit the key entirely to leave it unchanged.
  2. Coerce the field to a string before serializing the request body.
  3. If you only want to change color/fit, do not include the `url` key at all.

Example fix

// before: passing an object
body: JSON.stringify({ url: { src: img.href } })

// after: pass a string or null
body: JSON.stringify({ url: img ? img.href : null })
Defensive patterns

Strategy: type-guard

Validate before calling

function isStringOrNull(v) { return v === null || typeof v === 'string'; }
if (url !== undefined && !isStringOrNull(url)) {
  throw new Error('url must be a string or null');
}

Type guard

/** @returns {v is string | null} */
function isStringOrNull(v) { return v === null || typeof v === 'string'; }

Prevention

When it happens

Trigger: POST /set-desktop-bg with `url` set to a number, boolean, array, or object (anything that is not a string and not null).

Common situations: Client sends the raw value of a typed input without coercion (e.g. a numeric id, an object describing the image); a boolean flag accidentally placed under `url`; serialization produced an object instead of a URL string.

Related errors


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