# Causes of Fetch Errors When Downloading Stitch Designs and How to Fix URL Quoting Issues

> Fix Stitch design fetch errors caused by URL quoting with this guide. Learn to resolve network failures, redirect loops, and malformed URLs for successful downloads.

- Repository: [Google Labs Code/stitch-skills](https://github.com/google-labs-code/stitch-skills)
- Tags: how-to-guide
- Published: 2026-07-16

---

**Fetch errors when downloading Stitch designs typically result from network failures, redirect loops, or malformed URLs caused by improper quote handling in CSS parsers, which can be resolved by implementing robust quote detection and redirect capping.**

Stitch-design skills in the `google-labs-code/stitch-skills` repository download external resources like images, CSS, and HTML fragments using the `fetch` API. The extraction pipeline processes these assets through several TypeScript modules that handle URL parsing, inline resource extraction, and post-processing. Understanding the specific failure modes in [`snapshot.ts`](https://github.com/google-labs-code/stitch-skills/blob/main/snapshot.ts) and [`extract_inline_html.ts`](https://github.com/google-labs-code/stitch-skills/blob/main/extract_inline_html.ts) is essential for debugging failed imports and ensuring reliable design rendering.

## Common Causes of Fetch Errors in Stitch Designs

The `fetch` implementation in Stitch's static HTML extraction scripts fails primarily due to three architectural factors:

### Network-Level Problems

DNS failures, connection timeouts, non-200 HTTP responses, and CORS rejections all trigger fetch exceptions. According to the source code in [`extract_inline_html.ts`](https://github.com/google-labs-code/stitch-skills/blob/main/extract_inline_html.ts) at line 283 and [`snapshot.ts`](https://github.com/google-labs-code/stitch-skills/blob/main/snapshot.ts) at line 417, every `fetch` call wraps in a `try/catch` block that treats any thrown error as a failed resource. The system then falls back to the original inline reference rather than crashing the extraction process.

### Redirect Loops

Stitch assets often point to short-links or tracking URLs that redirect multiple times. The `fetchAndEncode` helper function caps redirects at 3 attempts using a `redirectCount` parameter. When this limit is exceeded (implemented in [`extract_inline_html.ts`](https://github.com/google-labs-code/stitch-skills/blob/main/extract_inline_html.ts) lines 287-348), the function aborts and returns an empty data-URI, preventing infinite loops and stack overflow.

### Invalid URL Quoting

CSS and HTML may contain URLs wrapped in single quotes, double quotes, or no quotes at all, sometimes including escaped characters. The parser in [`snapshot.ts`](https://github.com/google-labs-code/stitch-skills/blob/main/snapshot.ts) (lines 487-509) and [`post_process.ts`](https://github.com/google-labs-code/stitch-skills/blob/main/post_process.ts) (lines 179-187) must track opening quotes and stop at matching unescaped delimiters. When quote handling fails, the URL string passed to `fetch` contains stray characters like unmatched quotes or backslashes, resulting in 400/404 errors.

## How URL Quoting Issues Break Fetch Requests

When the Stitch parser encounters a `url(...)` or `@import` statement, it extracts the string between the parentheses. If the parser fails to account for the opening quote style, it either truncates the URL at the wrong delimiter, includes trailing quote characters in the fetched string, or mishandles escaped quotes (`\"` or `\'`). This produces malformed URLs such as `https://example.com/image.png"` (with trailing double quote) or `https://example.com/image.png\'s` (with escaped character included). When `fetch` receives these strings, it cannot resolve the DNS or path, resulting in 404 errors.

## The Fix: Implementing Robust URL Parsing and Fetch Logic

The `google-labs-code/stitch-skills` repository implements a four-step quote detection algorithm that eliminates these fetch failures:

### Step 1: Detect the Quoting Style

When parsing CSS text, the algorithm checks if the character immediately following the opening parenthesis is a single or double quote:

```typescript
// From plugins/stitch-design/skills/extract-static-html/scripts/snapshot.ts
let quote: string | null = null;
if (cssText[i] === '"' || cssText[i] === "'") {
  quote = cssText[i];               // Remember opening quote
  i++;                              // Move past the opening quote

```

### Step 2: Handle Escaped Characters

While reading the URL, the parser skips escaped characters to ensure that a backslash-protected quote doesn't prematurely terminate the string:

```typescript
  while (i < len && cssText[i] !== quote) {
    if (cssText[i] === '\\') i++;   // Skip escaped characters
    i++;
  }
  if (i < len) i++;                 // Skip closing quote

```

### Step 3: Process Unquoted URLs

If no opening quote is detected, the parser falls back to the CSS specification for unquoted URLs, stopping at whitespace or the closing parenthesis:

```typescript
} else {
  // Unquoted URL – stop at whitespace or ')'
  while (i < len && !/\s|\)/.test(cssText[i])) i++;
}

```

### Step 4: Cap Redirects to Prevent Loops

The `fetchAndEncode` function in [`extract_inline_html.ts`](https://github.com/google-labs-code/stitch-skills/blob/main/extract_inline_html.ts) implements recursive fetch with a hard limit of 3 redirects:

```typescript
// Fetch helper with redirect limit (extract_inline_html.ts)
function fetchAndEncode(url: string, timeout: number, redirectCount = 0): Promise<string> {
  if (redirectCount > 3) return Promise.reject('Too many redirects');
  return fetch(url, { timeout }).then(resp => {
    if (resp.status >= 300 && resp.status < 400 && resp.headers.get('location')) {
      const redirectUrl = new URL(resp.headers.get('location')!, url).toString();
      return fetchAndEncode(redirectUrl, timeout, redirectCount + 1);
    }
    return resp.arrayBuffer().then(buf => 
      `data:${resp.headers.get('content-type')};base64,${btoa(String.fromCharCode(...new Uint8Array(buf)))}`
    );
  });
}

```

## Summary

- **Network failures** in Stitch designs are caught by `try/catch` blocks in [`snapshot.ts`](https://github.com/google-labs-code/stitch-skills/blob/main/snapshot.ts) and [`extract_inline_html.ts`](https://github.com/google-labs-code/stitch-skills/blob/main/extract_inline_html.ts), allowing graceful fallbacks to inline references.
- **Redirect loops** are prevented by the `fetchAndEncode` function, which caps recursive redirects at 3 attempts before aborting with a rejection.
- **URL quoting errors** occur when CSS parsers fail to handle single, double, or escaped quotes, passing malformed strings to `fetch`.
- **Robust parsing** requires tracking opening quotes, skipping escaped characters, and handling unquoted URL syntax per CSS specifications.
- **Key files** for debugging fetch errors include [`snapshot.ts`](https://github.com/google-labs-code/stitch-skills/blob/main/snapshot.ts) (lines 487-509), [`post_process.ts`](https://github.com/google-labs-code/stitch-skills/blob/main/post_process.ts) (lines 179-187), and [`extract_inline_html.ts`](https://github.com/google-labs-code/stitch-skills/blob/main/extract_inline_html.ts) (lines 287-348).

## Frequently Asked Questions

### Why do Stitch design downloads fail with 404 errors despite valid URLs?

404 errors typically indicate that the URL parser included stray quote characters in the fetch string. When [`snapshot.ts`](https://github.com/google-labs-code/stitch-skills/blob/main/snapshot.ts) processes CSS with mixed quoting styles (single quotes, double quotes, or escaped characters), improper delimiter handling appends quotes to the URL path. Ensure the parser checks for opening quotes and advances past the closing quote before passing the string to `fetch`.

### How does the Stitch extraction pipeline handle infinite redirect loops?

The `fetchAndEncode` function in [`extract_inline_html.ts`](https://github.com/google-labs-code/stitch-skills/blob/main/extract_inline_html.ts) implements a `redirectCount` parameter that defaults to 0 and increments with each recursive call. When the count exceeds 3, the function rejects with 'Too many redirects', preventing stack overflow and returning an empty data-URI instead of hanging the extraction process.

### What causes CORS-related fetch errors in Stitch skills?

Cross-origin resource sharing (CORS) errors occur when external servers serving Stitch assets block requests from the extraction script's origin. These network-level failures are caught in the `try/catch` blocks at line 417 of [`snapshot.ts`](https://github.com/google-labs-code/stitch-skills/blob/main/snapshot.ts) and line 283 of [`extract_inline_html.ts`](https://github.com/google-labs-code/stitch-skills/blob/main/extract_inline_html.ts), triggering the fallback mechanism to use the original reference rather than the fetched content.

### How should escaped characters in CSS URLs be handled?

When parsing URLs in [`snapshot.ts`](https://github.com/google-labs-code/stitch-skills/blob/main/snapshot.ts) (lines 487-509), the algorithm detects backslash characters (`\`) and skips the next character to properly handle escaped quotes. This prevents the parser from terminating early when encountering `\'` or `\"` sequences inside quoted URLs, ensuring the complete URL reaches the `fetch` call without escape artifacts.