Mintplex-Labs/anything-llm · warning · Error
Failed to fetch logo!
Error message
Failed to fetch logo!
What it means
Thrown by System.fetchLogo when the GET to {fullApiUrl()}/system/logo?theme=... returns a non-2xx status OR returns 204 No Content. Notably this route sends NO auth headers (it must render on the login screen) and uses fullApiUrl() (absolute). The .catch() returns {isCustomLogo:false, logoURL:null}, so failure silently falls back to the default logo.
Source
Thrown at frontend/src/models/system.js:481
fetchLogo: async function () {
const url = new URL(`${fullApiUrl()}/system/logo`);
url.searchParams.append(
"theme",
localStorage.getItem("theme") || "default"
);
return await fetch(url, {
method: "GET",
cache: "no-cache",
})
.then(async (res) => {
if (res.ok && res.status !== 204) {
const isCustomLogo = res.headers.get("X-Is-Custom-Logo") === "true";
const blob = await res.blob();
const logoURL = URL.createObjectURL(blob);
return { isCustomLogo, logoURL };
}
throw new Error("Failed to fetch logo!");
})
.catch((e) => {
console.log(e);
return { isCustomLogo: false, logoURL: null };
});
},
fetchPfp: async function (id) {
return await fetch(`${API_BASE}/system/pfp/${id}`, {
method: "GET",
cache: "no-cache",
headers: baseHeaders(),
})
.then((res) => {
if (res.ok && res.status !== 204) return res.blob();
throw new Error("Failed to fetch pfp.");
})
.then((blob) => (blob ? URL.createObjectURL(blob) : null))
.catch(() => {View on GitHub (pinned to 526360e320)
Solutions
- Treat 204 as 'no custom logo' rather than an error — the guard conflates the two.
- Confirm fullApiUrl() returns the same origin that serves the /api routes.
- Check the server's logo storage path for a custom file.
- Ensure the reverse proxy preserves the ?theme= query string.
Example fix
// before
if (res.ok && res.status !== 204) { ... }
throw new Error("Failed to fetch logo!");
// after (204 is not an error)
if (res.status === 204) return { isCustomLogo: false, logoURL: null };
if (!res.ok) throw new Error(`Failed to fetch logo! (${res.status})`); Defensive patterns
Strategy: fallback
Validate before calling
// No auth header is sent; ensure fullApiUrl() origin serves /system/logo.
function sameOriginLogoUrl() {
try { return new URL(fullApiUrl()).origin === window.location.origin; }
catch { return false; }
} Type guard
/** @param {any} r @returns {r is {isCustomLogo:boolean, logoURL:string|null}} */
function isLogoResult(r) {
return r != null && typeof r.isCustomLogo === "boolean" && (r.logoURL === null || typeof r.logoURL === "string");
} Try / catch
const res = await System.fetchLogo();
if (!isLogoResult(res) || !res.logoURL) { renderDefaultLogo(); } Prevention
- Treat a 204 (no custom logo) as a normal state, not an error.
- Confirm fullApiUrl() resolves to the serving origin.
- Always have a default-logo fallback ready in the UI.
When it happens
Trigger: Calling fetchLogo() when the logo file is missing on disk (404), when the server returns 204 (no custom logo set — treated as an error here), when fullApiUrl() points at the wrong origin (CORS), or when the theme param is invalid.
Common situations: A 204 response from a deployment with no custom logo — this is actually a normal state but is treated as an error; fullApiUrl() resolves to a host that does not serve /system/logo; reverse proxy strips the theme query param.
Related errors
- Failed to get is default logo!
- Error removing logo!
- Error uploading logo.
- Failed to sync link content. ${reason}
- Failed to sync YouTube video transcript. ${reason}
AI-assisted analysis of Mintplex-Labs/anything-llm@526360e320 (2026-08-13).
Data as JSON: /api/errors/b89ed45d3967d91b.
Report an issue: GitHub.