itwanger/toBeBetterJavaer · error · Error

Downloaded file is empty

Error message

Downloaded file is empty

What it means

Thrown by downloadImage() in scripts/convert-mdnice-images-to-cdn.js when the response body, after being buffered into a Buffer, has zero bytes. A 2xx response with an image Content-Type but an empty body means nothing would be uploaded, so the script refuses before touching OSS.

Source

Thrown at scripts/convert-mdnice-images-to-cdn.js:373

}

async function downloadImage(url) {
  const response = await fetch(url, {
    redirect: "follow",
    headers: {
      "User-Agent": "toBeBetterJavaer-image-cdn/1.0",
    },
  });
  if (!response.ok) {
    throw new Error(`Download failed with HTTP ${response.status}`);
  }
  const contentType = normalizeContentType(response.headers.get("content-type"));
  if (contentType && !contentType.startsWith("image/") && contentType !== "application/octet-stream") {
    throw new Error(`Unexpected content type: ${contentType}`);
  }
  const body = Buffer.from(await response.arrayBuffer());
  if (body.length === 0) {
    throw new Error("Downloaded file is empty");
  }
  return { body, contentType };
}

function normalizeContentType(contentType) {
  if (!contentType) {
    return "";
  }
  return contentType.split(";")[0].trim().toLowerCase();
}

function contentTypeForPath(filePath) {
  const extension = path.extname(filePath).toLowerCase();
  switch (extension) {
    case ".png":
      return "image/png";
    case ".jpg":
    case ".jpeg":

View on GitHub (pinned to 6617f5fd0b)

Solutions

  1. Rerun the command — empty bodies from transient network faults usually resolve on retry
  2. Verify manually: `curl -o /tmp/x.png <url> && ls -l /tmp/x.png` to confirm the source serves bytes
  3. If the source is permanently empty, replace the image reference with a working copy of the asset
Defensive patterns

Strategy: retry

Validate before calling

const res = await fetch(url, { headers: { "User-Agent": "toBeBetterJavaer-image-cdn/1.0" } });
const len = Number(res.headers.get("content-length") || "-1");
if (len === 0) console.warn(`Source serves an empty body: ${url}`);

Try / catch

catch (err) { if (err.message === "Downloaded file is empty") { await sleep(backoff); return retryOnce(); } throw err; }

Prevention

When it happens

Trigger: Source server returns 200 with correct Content-Type and zero-length body (truncated upload on the origin, a bad proxy response, or a redirect chain that terminates in an empty stream). Requires --write mode since dry runs never download.

Common situations: Flaky upstream CDNs; interrupted origin uploads; middleboxes (corporate proxies, VPNs) returning empty bodies; rare but real on mobile hotspots.

Related errors


AI-assisted analysis of itwanger/toBeBetterJavaer@6617f5fd0b (2026-08-14). Data as JSON: /api/errors/a0484284f2d983df. Report an issue: GitHub.