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

  1. Verify the repo slug is a valid public GitHub repository (open https://github.com/<owner>/<repo> in a browser).
  2. Confirm actual.css exists at the repo root on the main branch (the fetcher hardcodes refs/heads/main/actual.css).
  3. If the branch is not main, restructure the repo so main is the default branch containing actual.css.
  4. Retry later or serve the CSS yourself via fetchDirectCss if GitHub rate-limits you (HTTP 403).
  5. 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

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


AI-assisted analysis of actualbudget/actual@d4334cb6e6 (2026-08-29). Data as JSON: /api/errors/7d8ddbe7ab9ab25c. Report an issue: GitHub.