{"record":{"id":"000c5367aeb8a8f9","repo":"BabylonJS/Babylon.js","slug":"no-url-provided","errorCode":null,"errorMessage":"No URL provided","messagePattern":"No URL provided","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/dev/gui/src/2D/advancedDynamicTexture.ts","lineNumber":1546,"sourceCode":"        const serialized = await AdvancedDynamicTexture._LoadURLContentAsync(url);\r\n        adt.parseSerializedObject(serialized, scaleToSize, urlRewriter);\r\n        return adt;\r\n    }\r\n\r\n    /**\r\n     * Recreate the content of the ADT from a url json\r\n     * @param url defines the url to load\r\n     * @param scaleToSize defines whether to scale to texture to the saved size\r\n     * @param urlRewriter defines an url rewriter to update urls before sending them to the controls\r\n     * @returns a promise that will resolve on success\r\n     */\r\n    public async parseFromURLAsync(url: string, scaleToSize?: boolean, urlRewriter?: (url: string) => string): Promise<AdvancedDynamicTexture> {\r\n        return await AdvancedDynamicTexture.ParseFromFileAsync(url, scaleToSize, this, urlRewriter);\r\n    }\r\n\r\n    private static async _LoadURLContentAsync(url: string, snippet: boolean = false): Promise<any> {\r\n        if (url === \"\") {\r\n            throw new Error(\"No URL provided\");\r\n        }\r\n\r\n        return await new Promise((resolve, reject) => {\r\n            const request = new WebRequest();\r\n            request.addEventListener(\"readystatechange\", () => {\r\n                if (request.readyState == 4) {\r\n                    if (request.status == 200) {\r\n                        let gui;\r\n                        if (snippet) {\r\n                            const payload = JSON.parse(JSON.parse(request.responseText).jsonPayload);\r\n                            gui = payload.encodedGui ? new TextDecoder(\"utf-8\").decode(DecodeBase64ToBinary(payload.encodedGui)) : payload.gui;\r\n                        } else {\r\n                            gui = request.responseText;\r\n                        }\r\n                        const serializationObject = JSON.parse(gui);\r\n                        resolve(serializationObject);\r\n                    } else {\r\n                        // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors\r","sourceCodeStart":1528,"sourceCodeEnd":1564,"githubUrl":"https://github.com/BabylonJS/Babylon.js/blob/0592b347b8a4ee0236089ea86a749cacfdb266d8/packages/dev/gui/src/2D/advancedDynamicTexture.ts#L1528-L1564","documentation":"AdvancedDynamicTexture._LoadURLContentAsync (shared by ParseFromURLAsync / snippet loading) rejects an empty string URL before issuing a WebRequest. The library cannot make an HTTP request without a URL, so it throws eagerly rather than failing inside the network layer.","triggerScenarios":"Calling AdvancedDynamicTexture.ParseFromURLAsync(url) or parseFromURLAsync(url) with an empty string (\"\") — often the result of an unset config value, an empty dataset attribute, or a failed path-joining/template interpolation.","commonSituations":"Loading a .gui/.json snippet file where a base-URL config or environment variable is empty; dynamic asset paths computed from user data that ended up blank; build pipelines stripping the asset URL.","solutions":["Pass a non-empty URL: check the value before calling, e.g. if (!url) throw/log before invoking parseFromURLAsync.","Fix the source of the empty string (config key, env var, DOM attribute, path join) that produced \"\".","Provide a default/fallback GUI asset URL when the primary one is missing."],"exampleFix":"// before\nconst url = config.guiUrl; // may be \"\"\nawait AdvancedDynamicTexture.ParseFromURLAsync(url);\n\n// after\nconst url = config.guiUrl;\nif (!url) {\n    throw new Error(\"config.guiUrl is not set\");\n}\nawait AdvancedDynamicTexture.ParseFromURLAsync(url);","handlingStrategy":"validation","validationCode":"if (typeof url !== \"string\" || url.trim() === \"\") {\n    throw new Error(\"GUI asset URL must be a non-empty string\");\n}\nawait AdvancedDynamicTexture.ParseFromURLAsync(url);","typeGuard":"function isNonEmptyUrl(v: unknown): v is string {\n    return typeof v === \"string\" && v.trim().length > 0;\n}","tryCatchPattern":"try {\n    await AdvancedDynamicTexture.ParseFromURLAsync(url);\n} catch (e) {\n    if (e instanceof Error && e.message === \"No URL provided\") {\n        console.error(\"GUI asset URL is empty — check config/env\");\n    } else {\n        throw e;\n    }\n}","preventionTips":["Validate config values (asset base URLs, env vars) at startup with fail-fast checks.","Avoid building URLs via string concatenation without checking intermediate parts.","Centralize asset URL resolution in one utility that guarantees a non-empty result or throws early."],"tags":["network","url","gui","input-validation"],"backgroundTag":"empty-url","analyzedSha":"0592b347b8a4ee0236089ea86a749cacfdb266d8","analyzedAt":"2026-08-30T15:11:20.442Z","schemaVersion":2},"datasetVersion":"2026-08-30T18:17:15.746Z"}