actualbudget/actual · error
Failed to fetch CSS from ${url}: ${response.status} ${respon
Error message
Failed to fetch CSS from ${url}: ${response.status} ${response.statusText} What it means
fetchDirectCss fetches theme CSS over HTTP (used by fetchThemeCss to pull actual.css from raw.githubusercontent.com). It throws this error whenever the HTTP response is not ok (status outside 200-299), e.g. 404 Not Found or 403 rate-limited. The message includes the requested URL and the exact status/statusText so you can tell whether the repo, branch, or file path is wrong.
Source
Thrown at packages/desktop-client/src/style/customThemes.ts:77
/**
* Try fetching actual.css from main branch.
*/
export function fetchThemeCss(repo: string): Promise<string> {
const url = new URL(
`https://raw.githubusercontent.com/${repo}/refs/heads/main/actual.css`,
);
url.searchParams.set('v', Date.now().toString());
return fetchDirectCss(url.toString());
}
/**
* Fetch CSS from a direct URL (not a GitHub repo).
*/
export async function fetchDirectCss(url: string): Promise<string> {
const response = await fetch(url, { cache: 'no-store' });
if (!response.ok) {
throw new Error(
`Failed to fetch CSS from ${url}: ${response.status} ${response.statusText}`,
);
}
return response.text();
}
/** Strip surrounding single or double quotes from a string. */
function stripQuotes(s: string): string {
const t = s.trim();
if (
(t.startsWith("'") && t.endsWith("'")) ||
(t.startsWith('"') && t.endsWith('"'))
) {
return t.slice(1, -1).trim();
}
return t;
}
View on GitHub (pinned to d4334cb6e6)
Solutions
- Verify the repo slug is a valid public GitHub repository (open https://github.com/<owner>/<repo> in a browser).
- Confirm actual.css exists at the repo root on the main branch (the fetcher hardcodes refs/heads/main/actual.css).
- If the branch is not main, restructure the repo so main is the default branch containing actual.css.
- Retry later or serve the CSS yourself via fetchDirectCss if GitHub rate-limits you (HTTP 403).
- Check network/proxy connectivity to raw.githubusercontent.com.
Example fix
// before
const css = await fetchThemeCss('actualbudget/unknow-theme');
// after
const repo = 'actualbudget/actual'; // verify repo exists and contains actual.css on main
const css = await fetchThemeCss(repo); Defensive patterns
Strategy: try-catch
Validate before calling
const url = `https://raw.githubusercontent.com/${repo}/refs/heads/main/actual.css`;
if (!/^[\w.-]+\/[\w.-]+$/.test(repo.trim())) throw new Error('repo must be owner/repo'); Try / catch
try {
const css = await fetchThemeCss(repo);
} catch (err) {
if ((err as Error).message.includes('Failed to fetch CSS')) {
// surface the URL/status to the user; offer manual CSS entry via fetchDirectCss fallback
} else throw err;
} Prevention
- Verify the repo publicly serves actual.css on the main branch before installing.
- Handle GitHub 403 rate limits with backoff.
- Provide a fallback path to paste CSS manually when the network fetch fails.
When it happens
Trigger: Calling fetchThemeCss('owner/repo') when the repo does not exist, has no actual.css on the main branch, or is private; or calling fetchDirectCss(url) directly with a URL that returns 404/403/5xx. Also triggered when raw.githubusercontent.com returns a non-2xx response (rate limiting, network proxy errors).
Common situations: Typo in the owner/repo slug in a custom theme catalog entry; theme repo renamed or its default branch changed from main to master; actual.css file moved or renamed; GitHub rate limiting (HTTP 403) after many fetches; offline or firewalled environment blocking raw.githubusercontent.com.
Related errors
- Failed to fetch catalog: ${response.statusText}
- ${text}
- API request redirected
- getServerErrorReason(json)
- text (raw server response body)
AI-assisted analysis of actualbudget/actual@d4334cb6e6 (2026-08-29).
Data as JSON: /api/errors/7d8ddbe7ab9ab25c.
Report an issue: GitHub.