{"id":17788307,"url":"https://github.com/nickytonline/remix-node-fetch-request-vs-deno-request-bug-repro","last_synced_at":"2025-04-02T00:28:09.993Z","repository":{"id":78822621,"uuid":"488351249","full_name":"nickytonline/remix-node-fetch-request-vs-deno-request-bug-repro","owner":"nickytonline","description":"See https://github.com/remix-run/remix/issues/3003","archived":false,"fork":false,"pushed_at":"2022-05-03T20:32:37.000Z","size":5,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-02-07T15:45:38.925Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nickytonline.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-05-03T20:19:03.000Z","updated_at":"2022-05-03T20:19:14.000Z","dependencies_parsed_at":null,"dependency_job_id":"1c853d1c-819d-4fe6-ab41-a420c2996fe6","html_url":"https://github.com/nickytonline/remix-node-fetch-request-vs-deno-request-bug-repro","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nickytonline%2Fremix-node-fetch-request-vs-deno-request-bug-repro","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nickytonline%2Fremix-node-fetch-request-vs-deno-request-bug-repro/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nickytonline%2Fremix-node-fetch-request-vs-deno-request-bug-repro/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nickytonline%2Fremix-node-fetch-request-vs-deno-request-bug-repro/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nickytonline","download_url":"https://codeload.github.com/nickytonline/remix-node-fetch-request-vs-deno-request-bug-repro/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246733508,"owners_count":20824962,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-27T10:18:24.185Z","updated_at":"2025-04-02T00:28:09.976Z","avatar_url":"https://github.com/nickytonline.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Serverless functions with node-fetch for Request vs. Edge functions with spec compliant deno's Request\n\nFor context, see https://github.com/remix-run/remix/issues/3003\n\nIt turns out deno is throwing because deno is spec compliant for `Request`. I did a minimal repro and since Remix is using `node-fetch`, there is something in there that is not spec compliant that masks the issue.\n\nI'm simulating what this bit of code does in Remix\n\n```javascript\nfunction stripIndexParam(request) {\n  let url = new URL(request.url);\n  let indexValues = url.searchParams.getAll(\"index\");\n  url.searchParams.delete(\"index\");\n  let indexValuesToKeep = [];\n  for (let indexValue of indexValues) {\n    if (indexValue) {\n      indexValuesToKeep.push(indexValue);\n    }\n  }\n  for (let toKeep of indexValuesToKeep) {\n    url.searchParams.append(\"index\", toKeep);\n  }\n  return new Request(url.href, request);\n}\nfunction stripDataParam(request) {\n  let url = new URL(request.url);\n  url.searchParams.delete(\"_data\");\n  return new Request(url.href, request);\n}\n\nasync function callRouteAction({\n  loadContext,\n  match,\n  request\n}) {\n  ...\n\n  let result;\n\n  try {\n    result = await action({\n      request: stripDataParam(stripIndexParam(request)),\n      context: loadContext,\n      params: match.params\n    });\n  } catch (error) {\n    if (!isResponse(error)) {\n      throw error;\n    }\n\n  ...\n}\n```\n\nClear skies in Node.js with node-fetch\n\n```javascript\n/** Run node index.js and you should see the following output:\n\nbody used: false\n{ json: { message: 'Hello world!' } }\nbody used: false\n{ json: { message: 'Hello world!' } }\n\n */\n(async () =\u003e {\n  const { default: fetch, Request} = await import('node-fetch');\n  const firstRequest = new Request(\"https://post.deno.dev\", {\n    method: \"POST\",\n    body: JSON.stringify({\n      message: \"Hello world!\",\n    }),\n    headers: {\n      \"content-type\": \"application/json\",\n    },\n  });\n  const secondRequest = new Request('https://post.deno.dev', firstRequest);\n\n  try {\n    console.log(`body used: ${firstRequest.bodyUsed}`);\n    const firstResponse = await fetch(firstRequest);\n    const firstJson = await firstResponse.json();\n    console.log(firstJson);\n    console.log(`body used: ${firstRequest.bodyUsed}`);\n\n    const secondResponse = await fetch(secondRequest);\n    const secondJson = await secondResponse.json(); // No boom. All good because secondResponse.bodyUsed is false.\n    console.log(secondJson);\n  } catch (error) {\n    console.error(error);\n  }\n})();\n```\n\nRough waters as expected in specs compliant land with deno and the native Request object.\n\n```typescript\n/** Run deno run --allow-all --unstable ./index.ts and you should see the following output:\n\nbody used: false\n{ json: { message: \"Hello world!\" } }\nbody used: true\nTypeError: Input request's body is unusable.\n    at new Request (deno:ext/fetch/23_request.js:325:17)\n    at deno:ext/fetch/26_fetch.js:422:29\n    at new Promise (\u003canonymous\u003e)\n    at fetch (deno:ext/fetch/26_fetch.js:418:20)\n    at file:///Users/nicktaylor/dev/deno-request-demo/index.ts:18:34\n\n */\nconst firstRequest = new Request(\"https://post.deno.dev\", {\n  method: \"POST\",\n  body: JSON.stringify({\n    message: \"Hello world!\",\n  }),\n  headers: {\n    \"content-type\": \"application/json\",\n  },\n});\nconst secondRequest = new Request('https://post.deno.dev', firstRequest);\n\ntry {\n  console.log(`body used: ${firstRequest.bodyUsed}`)\n  const firstResponse = await fetch(firstRequest)\n  const firstJson = await firstResponse.json()\n  console.log(firstJson)\n  console.log(`body used: ${firstRequest.bodyUsed}`)\n\n  const secondResponse = await fetch(secondRequest)\n  const secondJson = await secondResponse.json() // 💥 boom!\n  console.log(secondJson)\n} catch (error) {\n  console.error(error);\n}\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnickytonline%2Fremix-node-fetch-request-vs-deno-request-bug-repro","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnickytonline%2Fremix-node-fetch-request-vs-deno-request-bug-repro","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnickytonline%2Fremix-node-fetch-request-vs-deno-request-bug-repro/lists"}