perspective-dev/perspective · error · TypeError

TileSourceSpec.subdomains must be an array of non-empty…

Error message

TileSourceSpec.subdomains must be an array of non-empty strings

What it means

parseTileSourceSpec normalizes the optional `subdomains` field: if present it must be an array whose every element is a non-empty string. Passing a single string, a list containing null/numbers/empty strings, or another non-array value triggers this guard. Note the default is [] when the field is absent, so only a wrong-typed value fires.

Solutions

  1. Pass subdomains as an array of strings, e.g. ["a","b","c"]
  2. Wrap a single subdomain in an array: subdomains: ["0"]
  3. Remove the field entirely if no subdomains are needed (it defaults to an empty array)
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at packages/viewer-charts/src/ts/map/tile-source.ts:163 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of perspective-dev/perspective@11c8238c0c (2026-09-09). Data as JSON: /api/errors/3a6db8a2172d94b3. Report an issue: GitHub.

Appendix: source

Thrown at packages/viewer-charts/src/ts/map/tile-source.ts:163

    const id = str("id");
    const label = str("label");
    const template = str("template");
    const attribution = str("attribution");
    for (const placeholder of ["{z}", "{x}", "{y}"]) {
        if (!template.includes(placeholder)) {
            throw new TypeError(
                `TileSourceSpec.template must contain "${placeholder}"`,
            );
        }
    }

    const rawSubdomains = raw["subdomains"] ?? [];
    if (
        !Array.isArray(rawSubdomains) ||
        rawSubdomains.some((s) => typeof s !== "string" || s.length === 0)
    ) {
        throw new TypeError(
            "TileSourceSpec.subdomains must be an array of non-empty strings",
        );
    }

    const subdomains = Object.freeze([...rawSubdomains] as string[]);
    if (template.includes("{s}") && subdomains.length === 0) {
        throw new TypeError(
            'TileSourceSpec.template uses "{s}" but no subdomains were given',
        );
    }

    const num = (key: string, dflt: number): number => {
        const v = raw[key];
        if (v === undefined) {
            return dflt;
        }

        if (typeof v !== "number" || !Number.isFinite(v) || v <= 0) {

View on GitHub (pinned to 11c8238c0c)