remix-run/react-router · error · CopyTemplateError

There was a problem extracting the file from the provided te

Error message

There was a problem extracting the file from the provided template.  Template URL: `${tarballUrl}`  Destination directory: `${downloadPath}`

What it means

Thrown inside the download pipeline's try/catch when the streamed tar extraction of a remotely-downloaded tarball fails. After a successful 200 fetch, the response body is piped through a PassThrough into gunzip -> tar.extract with custom map/ignore hooks; any rejection there (gunzip error, bad tar header, write error to downloadPath) is caught and rewrapped. The message records the original tarballUrl and downloadPath but, unlike the local-tarball variant (error 2), does NOT append the underlying cause.

Source

Thrown at packages/create-react-router/copy-template.ts:332

              filePathHasFiles = true;
              header.name = header.name.replace(filePath, "");
            } else {
              header.name = "__IGNORE__";
            }
          }

          return header;
        },
        ignore(_filename, header) {
          if (!header) {
            throw Error("Header is undefined");
          }
          return header.name === "__IGNORE__";
        },
      }),
    );
  } catch {
    throw new CopyTemplateError(
      "There was a problem extracting the file from the provided template." +
        `  Template URL: \`${tarballUrl}\`` +
        `  Destination directory: \`${downloadPath}\``,
    );
  }

  if (filePath && !filePathHasFiles) {
    throw new CopyTemplateError(
      `The path "${filePath}" was not found in this ${
        isGithubUrl ? "GitHub repo." : "tarball."
      }`,
    );
  }
}

// Copied from react-router-node/stream.ts
async function writeReadableStreamToWritable(
  stream: ReadableStream,

View on GitHub (pinned to 1fd704a7da)

Solutions

  1. Download the URL manually (curl -L -o out.tar.gz <url>) and run tar -tzf out.tar.gz to confirm it is a valid gzip+tar.
  2. If the body is HTML (sign-in page), the source requires auth — pass --token or use a public URL.
  3. Free up space or change TMPDIR for downloadPath.
  4. Retry to rule out a transient partial download; if on a corporate proxy, bypass it for codeload.github.com / api.github.com.
  5. Run with --debug to see which sub-step logged last before the throw.

Example fix

// verify what the server is actually returning
curl -sL https://codeload.github.com/acme/tpl/tar.gz/main | file -
# if it reports HTML, the URL needs auth:
create-react-router my-app --token $GITHUB_TOKEN --template https://github.com/acme/tpl/tree/main
Defensive patterns

Strategy: validation

Validate before calling

// Verify the remote URL actually serves a gzip tarball, not HTML
async function urlServesTarball(url: string, token?: string) {
  const h: HeadersInit = {};
  if (token) h.Authorization = `token ${token}`;
  const r = await fetch(url, { headers: h });
  if (!r.ok) return false;
  const ct = r.headers.get('content-type') ?? '';
  if (ct.includes('text/html')) return false;
  const buf = await r.arrayBuffer();
  // gzip magic bytes 1f 8b
  const head = new Uint8Array(buf.slice(0, 2));
  return head[0] === 0x1f && head[1] === 0x8b;
}

Try / catch

try { await copyTemplate(url, dest, opts); }
catch (e) {
  if (e instanceof CopyTemplateError && /Template URL:/.test(e.message)) {
    // download manually, confirm it's gzip, and retry with --token if it was HTML
  } else throw e;
}

Prevention

When it happens

Trigger: The remote server returned 200 but the body is HTML (e.g. a login page) instead of gzip; the tarball is truncated mid-stream; tar-fs rejects a header (e.g. absolute path outside downloadPath); disk full while writing to downloadPath; the map/ignore hook throws 'Header is undefined'.

Common situations: Private repo redirect that serves an HTML sign-in page with status 200; CDN serving a partial cached object; downloadPath is in /tmp on a constrained volume; mismatch between Content-Encoding and actual bytes (double-gzip).

Related errors


AI-assisted analysis of remix-run/react-router@1fd704a7da (2026-08-12). Data as JSON: /api/errors/f417b57905779436. Report an issue: GitHub.