ruvnet/ruflo · error · Error

Failed to fetch (${res.status})

Error message

Failed to fetch (${res.status})

What it means

The URL-fetch proxy request returned a non-OK HTTP status, and the response body was empty, so handleSubmit() synthesized this error with the proxy's status code. The server-side /api/fetch-url proxy refused or failed the fetch (bad URL upstream, size/type rejection, or proxy error) — not a client-side URL-format problem, which was validated earlier.

Source

Thrown at ruflo/src/ruvocal/src/lib/components/chat/UrlFetchModal.svelte:83

	}

	async function handleSubmit() {
		errorMsg = "";
		const trimmed = urlValue.trim();
		if (!isHttpsUrl(trimmed)) {
			errorMsg = "Enter a valid HTTPS URL.";
			return;
		}
		loading = true;
		try {
			// Use server proxy directly for one URL to validate size/types before creating File
			const params = new URLSearchParams({ url: trimmed });
			if (acceptMimeTypes.length > 0) params.set("accept", acceptMimeTypes.join(","));
			const proxyUrl = `${base}/api/fetch-url?${params}`;
			const res = await fetch(proxyUrl);
			if (!res.ok) {
				const txt = await res.text();
				throw new Error(txt || `Failed to fetch (${res.status})`);
			}
			const forwardedType = res.headers.get("x-forwarded-content-type");
			const blob = await res.blob();
			const mimeType = pickSafeMime(forwardedType, blob.type, trimmed);
			// Optional client-side mime filter (same wildcard semantics as dropzone)
			if (acceptMimeTypes.length > 0 && mimeType && !matchesAllowed(mimeType, acceptMimeTypes)) {
				throw new Error("File type not allowed.");
			}
			const disp = res.headers.get("content-disposition");
			const filename = (() => {
				const filenameStar = disp?.match(/filename\*=UTF-8''([^;]+)/i)?.[1];
				if (filenameStar) {
					const cleaned = filenameStar.trim().replace(/['"]/g, "");
					try {
						return decodeURIComponent(cleaned);
					} catch {
						return cleaned;
					}

View on GitHub (pinned to fa13ee4ad6)

Solutions

  1. Check the URL and network connectivity; inspect the HTTP status code for the underlying cause.
  2. Retry with backoff for transient failures; surface the status code to the user for 4xx responses.
Defensive patterns

Strategy: try-catch

When it happens

Trigger: Thrown at ruflo/src/ruvocal/src/lib/components/chat/UrlFetchModal.svelte:83 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of ruvnet/ruflo@fa13ee4ad6 (2026-08-18). Data as JSON: /api/errors/19ec23cf571e6895. Report an issue: GitHub.