{"record":{"id":"3a6db8a2172d94b3","repo":"perspective-dev/perspective","slug":"tilesourcespec-subdomains-must-be-an-array-of-non","errorCode":null,"errorMessage":"TileSourceSpec.subdomains must be an array of non-empty strings","messagePattern":"TileSourceSpec\\.subdomains must be an array of non-empty strings","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"packages/viewer-charts/src/ts/map/tile-source.ts","lineNumber":163,"sourceCode":"\n    const id = str(\"id\");\n    const label = str(\"label\");\n    const template = str(\"template\");\n    const attribution = str(\"attribution\");\n    for (const placeholder of [\"{z}\", \"{x}\", \"{y}\"]) {\n        if (!template.includes(placeholder)) {\n            throw new TypeError(\n                `TileSourceSpec.template must contain \"${placeholder}\"`,\n            );\n        }\n    }\n\n    const rawSubdomains = raw[\"subdomains\"] ?? [];\n    if (\n        !Array.isArray(rawSubdomains) ||\n        rawSubdomains.some((s) => typeof s !== \"string\" || s.length === 0)\n    ) {\n        throw new TypeError(\n            \"TileSourceSpec.subdomains must be an array of non-empty strings\",\n        );\n    }\n\n    const subdomains = Object.freeze([...rawSubdomains] as string[]);\n    if (template.includes(\"{s}\") && subdomains.length === 0) {\n        throw new TypeError(\n            'TileSourceSpec.template uses \"{s}\" but no subdomains were given',\n        );\n    }\n\n    const num = (key: string, dflt: number): number => {\n        const v = raw[key];\n        if (v === undefined) {\n            return dflt;\n        }\n\n        if (typeof v !== \"number\" || !Number.isFinite(v) || v <= 0) {","sourceCodeStart":145,"sourceCodeEnd":181,"githubUrl":"https://github.com/perspective-dev/perspective/blob/11c8238c0c9c0b9e490b5a6a2dc277afad1e980a/packages/viewer-charts/src/ts/map/tile-source.ts#L145-L181","documentation":"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.","triggerScenarios":"Thrown at packages/viewer-charts/src/ts/map/tile-source.ts:163 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Pass subdomains as an array of strings, e.g. [\"a\",\"b\",\"c\"]","Wrap a single subdomain in an array: subdomains: [\"0\"]","Remove the field entirely if no subdomains are needed (it defaults to an empty array)"],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"11c8238c0c9c0b9e490b5a6a2dc277afad1e980a","analyzedAt":"2026-09-09T00:35:19.377Z","contentChangedAt":"2026-09-09T00:35:19.377Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}