{"record":{"id":"9cb8e8a843fd023b","repo":"BabylonJS/Babylon.js","slug":"filename-is-required-when-using-a-url","errorCode":null,"errorMessage":"filename is required when using a URL","messagePattern":"filename is required when using a URL","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/dev/loaders/src/SPLAT/sog.pure.ts","lineNumber":136,"sourceCode":"                // Extract pixel data (RGBA per pixel)\r\n                const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);\r\n                resolve({ bits: new Uint8Array(imageData.data.buffer), width: imageData.width, height: imageData.height });\r\n            } catch (error) {\r\n                // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors\r\n                reject(`Error loading image ${image.src} with exception: ${error}`);\r\n            }\r\n        };\r\n        image.onerror = (error) => {\r\n            // eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors\r\n            reject(`Error loading image ${image.src} with exception: ${error}`);\r\n        };\r\n\r\n        image.crossOrigin = \"anonymous\"; // To avoid CORS issues\r\n        let objectUrl: string | undefined;\r\n        if (typeof rootUrlOrData === \"string\") {\r\n            // old behavior: URL + filename\r\n            if (!filename) {\r\n                throw new Error(\"filename is required when using a URL\");\r\n            }\r\n            image.src = rootUrlOrData + filename;\r\n        } else {\r\n            // new behavior: Uint8Array\r\n            const blob = new Blob([rootUrlOrData as any], { type: \"image/webp\" });\r\n            objectUrl = URL.createObjectURL(blob);\r\n            image.src = objectUrl;\r\n        }\r\n    });\r\n    return await promise;\r\n}\r\n\r\nasync function ParseSogDatas(data: SOGRootData, imageDataArrays: IWebPImage[], scene: Scene): Promise<IParsedSplat> {\r\n    const splatCount = data.count ? data.count : data.means.shape[0];\r\n    const rowOutputLength = 3 * 4 + 3 * 4 + 4 + 4; // 32\r\n    const buffer = new ArrayBuffer(rowOutputLength * splatCount);\r\n\r\n    const position = new Float32Array(buffer);\r","sourceCodeStart":118,"sourceCodeEnd":154,"githubUrl":"https://github.com/BabylonJS/Babylon.js/blob/0592b347b8a4ee0236089ea86a749cacfdb266d8/packages/dev/loaders/src/SPLAT/sog.pure.ts#L118-L154","documentation":"LoadWebpImageData supports two input modes: a URL root plus a filename (old API) or a raw Uint8Array of WebP bytes (new API). When given a string URL, it builds image.src as rootUrlOrData + filename; without a filename the resulting URL would be invalid, so it throws immediately. Callers must switch to the Uint8Array form or provide the filename.","triggerScenarios":"Calling LoadWebpImageData (directly or through SOG parsing paths like loadMeansImageAsync) with a string rootUrl but filename omitted or empty string.","commonSituations":"Migrating code between API versions where the filename argument was dropped; calling the internal function with just a URL; passing a data URL string while expecting the bytes path.","solutions":["Pass the filename argument alongside the root URL: LoadWebpImageData(rootUrl, fileName, engine).","Prefer the new API: decode the WebP to a Uint8Array and pass the bytes instead of a URL.","If you have a full URL (not root + name), pass an empty-suffix arrangement by giving the complete file name as the second argument.","For data URLs, convert to Uint8Array first since the string path always appends filename."],"exampleFix":"// before\nLoadWebpImageData(\"https://cdn.example.com/sog/\", undefined, engine); // throws\n// after\nLoadWebpImageData(\"https://cdn.example.com/sog/\", \"means_l.webp\", engine);\n// or with bytes:\nconst bytes = new Uint8Array(await fetch(url + \"means_l.webp\").then(r => r.arrayBuffer()));\nLoadWebpImageData(bytes, \"\", engine);","handlingStrategy":"validation","validationCode":"if (typeof rootUrlOrData === \"string\" && !filename) {\n  throw new Error(\"Provide a filename when loading SOG images from a root URL\");\n}","typeGuard":"function isByteInput(input: string | Uint8Array, filename?: string): input is Uint8Array {\n  return input instanceof Uint8Array || (typeof input === \"string\" && !!filename);\n}","tryCatchPattern":"try {\n  await loadMeansImageAsync(rootUrl, filename, engine);\n} catch (e) {\n  if (String(e.message) === \"filename is required when using a URL\") {\n    // switch to bytes path\n    const bytes = new Uint8Array(await fetch(rootUrl + \"means_l.webp\").then(r => r.arrayBuffer()));\n    await loadMeansImageAsync(bytes, \"\", engine);\n  } else throw e;\n}","preventionTips":["Always pass both rootUrl and filename together, or switch fully to the Uint8Array API.","Update call sites after API migration — the old URL-only signature is no longer valid.","Fetch and pass bytes explicitly to avoid string-concatenation URL pitfalls.","Validate inputs (typeof check) before invoking internal loader functions."],"tags":["splat","sog","validation","api-misuse","url"],"backgroundTag":"missing-required-argument","analyzedSha":"0592b347b8a4ee0236089ea86a749cacfdb266d8","analyzedAt":"2026-08-30T15:11:20.442Z","schemaVersion":2},"datasetVersion":"2026-08-30T18:17:15.746Z"}