perspective-dev/perspective · error · TypeError

TileSourceSpec.template uses

Error message

TileSourceSpec.template uses "{s}" but no subdomains were given

What it means

Cross-field consistency check in parseTileSourceSpec: a template containing the {s} placeholder needs at least one entry in `subdomains` to substitute for it. The spec references subdomain cycling but supplies none, so at runtime the URL would contain a literal {s}; the validator rejects it before any tile is requested.

Solutions

  1. Provide subdomains: ["a","b","c"] alongside the {s} template
  2. Remove {s} from the template URL if the provider serves from a single host
  3. Use a full explicit template like https://a.tile.example.com/{z}/{x}/{y}.png instead of {s}
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at packages/viewer-charts/src/ts/map/tile-source.ts:170 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/b83ddb4bcdc4fe27. Report an issue: GitHub.

Appendix: source

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

            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) {
            throw new TypeError(
                `TileSourceSpec.${key} must be a positive number`,
            );
        }

        return v;
    };

View on GitHub (pinned to 11c8238c0c)