{"record":{"id":"f417b57905779436","repo":"remix-run/react-router","slug":"there-was-a-problem-extracting-the-file-from-the-p-f417b5","errorCode":null,"errorMessage":"There was a problem extracting the file from the provided template.  Template URL: `${tarballUrl}`  Destination directory: `${downloadPath}`","messagePattern":"There was a problem extracting the file from the provided template\\.  Template URL: `(.+?)`  Destination directory: `(.+?)`","errorType":"exception","errorClass":"CopyTemplateError","httpStatus":null,"severity":"error","filePath":"packages/create-react-router/copy-template.ts","lineNumber":332,"sourceCode":"              filePathHasFiles = true;\n              header.name = header.name.replace(filePath, \"\");\n            } else {\n              header.name = \"__IGNORE__\";\n            }\n          }\n\n          return header;\n        },\n        ignore(_filename, header) {\n          if (!header) {\n            throw Error(\"Header is undefined\");\n          }\n          return header.name === \"__IGNORE__\";\n        },\n      }),\n    );\n  } catch {\n    throw new CopyTemplateError(\n      \"There was a problem extracting the file from the provided template.\" +\n        `  Template URL: \\`${tarballUrl}\\`` +\n        `  Destination directory: \\`${downloadPath}\\``,\n    );\n  }\n\n  if (filePath && !filePathHasFiles) {\n    throw new CopyTemplateError(\n      `The path \"${filePath}\" was not found in this ${\n        isGithubUrl ? \"GitHub repo.\" : \"tarball.\"\n      }`,\n    );\n  }\n}\n\n// Copied from react-router-node/stream.ts\nasync function writeReadableStreamToWritable(\n  stream: ReadableStream,","sourceCodeStart":314,"sourceCodeEnd":350,"githubUrl":"https://github.com/remix-run/react-router/blob/1fd704a7dabcbe3ae09d7387b460e6acaba30ec1/packages/create-react-router/copy-template.ts#L314-L350","documentation":"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.","triggerScenarios":"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'.","commonSituations":"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).","solutions":["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.","If the body is HTML (sign-in page), the source requires auth — pass --token or use a public URL.","Free up space or change TMPDIR for downloadPath.","Retry to rule out a transient partial download; if on a corporate proxy, bypass it for codeload.github.com / api.github.com.","Run with --debug to see which sub-step logged last before the throw."],"exampleFix":"// verify what the server is actually returning\ncurl -sL https://codeload.github.com/acme/tpl/tar.gz/main | file -\n# if it reports HTML, the URL needs auth:\ncreate-react-router my-app --token $GITHUB_TOKEN --template https://github.com/acme/tpl/tree/main","handlingStrategy":"validation","validationCode":"// Verify the remote URL actually serves a gzip tarball, not HTML\nasync function urlServesTarball(url: string, token?: string) {\n  const h: HeadersInit = {};\n  if (token) h.Authorization = `token ${token}`;\n  const r = await fetch(url, { headers: h });\n  if (!r.ok) return false;\n  const ct = r.headers.get('content-type') ?? '';\n  if (ct.includes('text/html')) return false;\n  const buf = await r.arrayBuffer();\n  // gzip magic bytes 1f 8b\n  const head = new Uint8Array(buf.slice(0, 2));\n  return head[0] === 0x1f && head[1] === 0x8b;\n}","typeGuard":null,"tryCatchPattern":"try { await copyTemplate(url, dest, opts); }\ncatch (e) {\n  if (e instanceof CopyTemplateError && /Template URL:/.test(e.message)) {\n    // download manually, confirm it's gzip, and retry with --token if it was HTML\n  } else throw e;\n}","preventionTips":["For private repos, always pass --token to avoid HTML sign-in responses.","Confirm TMPDIR has adequate free space.","Bypass corporate proxies for codeload/api.github.com.","Use --debug to surface the failing sub-step."],"tags":["network","tarball","streaming","github-api","create-react-router"],"backgroundTag":null,"analyzedSha":"1fd704a7dabcbe3ae09d7387b460e6acaba30ec1","analyzedAt":"2026-08-12T13:54:57.804Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}