BabylonJS/Babylon.js · error
SmartAssetSerializer: Failed to fetch "${source}" — HTTP ${r
Error message
SmartAssetSerializer: Failed to fetch "${source}" — HTTP ${response.status} What it means
ReadJsonSourceAsync fetches JSON from a URL when given a string source. If the fetch completes but response.ok is false (any non-2xx HTTP status), the function throws this error embedding the requested source URL and the HTTP status code. It signals the remote JSON could not be retrieved, as opposed to a network failure or malformed JSON body.
Source
Thrown at packages/dev/core/src/SmartAssets/smartAssetSerializer.ts:117
*/
export function MakeRelative(url: string, baseUrl: string): string {
const folder = Tools.GetFolderPath(baseUrl);
if (url.startsWith(folder)) {
return url.substring(folder.length);
}
return url;
}
/**
* Reads a JSON source from a string URL, File object, or pre-parsed object.
* @param source - The source to read.
* @returns A promise resolving to the parsed JSON data.
*/
export async function ReadJsonSourceAsync(source: string | File | object): Promise<unknown> {
if (typeof source === "string") {
const response = await fetch(source);
if (!response.ok) {
throw new Error(`SmartAssetSerializer: Failed to fetch "${source}" — HTTP ${response.status}`);
}
return await response.json();
}
if (source instanceof File) {
return await new Promise<unknown>((resolve, reject) => {
const reader = new FileReader();
reader.onload = () => {
try {
resolve(JSON.parse(reader.result as string));
} catch {
reject(new Error(`SmartAssetSerializer: Failed to parse JSON from file "${source.name}".`));
}
};
reader.onerror = () => reject(new Error(`SmartAssetSerializer: Failed to read file "${source.name}".`));
reader.readAsText(source);
});
}View on GitHub (pinned to 0592b347b8)
Solutions
- Open the URL from the error message in a browser or curl -I to confirm the HTTP status and fix the path/filename (404 usually means wrong URL).
- If 401/403, add authentication (signed URL, token header) or make the asset publicly readable.
- Verify the deployment: re-upload the missing JSON asset to the CDN and update the asset map url entries.
- Add retry with backoff for transient 5xx responses, and check server logs if the status is 500.
Example fix
// before
const data = await ReadJsonSourceAsync("https://cdn.example.com/assets/assest-map.json"); // 404 typo
// after
const url = "https://cdn.example.com/assets/asset-map.json";
const res = await fetch(url, { method: "HEAD" });
if (!res.ok) throw new Error(`Asset JSON unavailable: ${res.status} ${url}`);
const data = await ReadJsonSourceAsync(url); Defensive patterns
Strategy: retry
Validate before calling
async function assertReachable(url) {
const res = await fetch(url, { method: "HEAD" });
if (!res.ok) throw new Error(`Pre-check failed for ${url}: HTTP ${res.status}`);
} Try / catch
async function loadJsonWithRetry(url, retries = 3) {
for (let i = 0; ; i++) {
try {
return await ReadJsonSourceAsync(url);
} catch (e) {
const m = e.message.match(/HTTP (\d+)/);
const status = m && Number(m[1]);
if (status && status >= 500 && i < retries) { await new Promise(r => setTimeout(r, 2 ** i * 250)); continue; }
if (status === 404 || status === 403) console.error(`Asset JSON ${status} at ${url}: fix URL or auth`);
throw e;
}
}
} Prevention
- HEAD-check asset URLs in CI so broken CDN links are caught before release.
- Prefer relative, versioned paths generated by the build over hand-typed URLs.
- Ensure private buckets serve via signed URLs or correct public-read ACL.
- Monitor CDN/server logs for 4xx/5xx on asset JSON routes.
When it happens
Trigger: Calling ReadJsonSourceAsync("https://host/file.json") (or the SmartAsset serializer import/registry paths that call it via 'raw') where the server responds 404 (file not found), 403 (forbidden/private asset), 401, 500, or any other non-OK status.
Common situations: Typo in the asset URL or wrong path/filename on the CDN; asset uploaded to a private bucket without signed URL; CORS/proxy returning 403; file deleted or moved after the asset map was authored; server outage returning 5xx; staging URL referenced from production or vice versa.
Understand the failure class
Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.
Related errors
- Failed to fetch image "${url}": ${response.status} ${respons
- Failed to fetch KTX2 file "${data}": ${response.status} ${re
- Unable to save your ${entityName ?? "content"}: ${e}
- Unable to load your ${entityName ?? "content"}: ${e}
- Unable to load the snippet ${snippetId}
AI-assisted analysis of BabylonJS/Babylon.js@0592b347b8 (2026-08-30).
Data as JSON: /api/errors/dbec934f62aadef2.
Report an issue: GitHub.