cloudflare / miniflare

🔥 Fully-local simulator for Cloudflare Workers. For the latest version, see https://github.com/cloudflare/workers-sdk/tree/main/packages/miniflare.

Home Page:https://miniflare.dev

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Failed to parse URL from [object Object]

Maximus169 opened this issue · comments

commented

I tried to upgrade from 2.10.0 to 2.11.0 and failed with the issue:

[mf:err] POST /api/endpoint/1: TypeError: Failed to parse URL from [object Object] at new Request (/Users/Maxim/project/node_modules/undici/lib/fetch/request.js:82:15) at new Request (/Users/Maxim/project/node_modules/miniflare/node_modules/@miniflare/core/src/standards/http.ts:393:13)

I run the code with 16.13 node version

commented

I didn't notice but it can be related to this #144

Hey! 👋 Are you able to share your package-lock.json file? Does the suggested fix in that issue of deleting your node_modules and package-lock.json file (after taking a backup), then re-running npm install work for you?

This seems to be a thing when I use yarn.

I'm trying to run a wasm worker (index.wasm + shim.mjs) locally, but it fails with this same error when using 2.11.0 while working perfectly fine with 2.10.0.

So, this happens to be not an issue anymore after I removed Wrangler my package.json as a dependency. Works fine with Yarn on 2.10.0 and 2.11.0 as well. The comments on #144 have been helpful

I my case I don't have a package.json at all though. I installed miniflare globally with yarn global add (maybe this was causing the issue?), and then on the project side it's just wrangler.toml and Cargo.toml.

In fact I've tried isolating the build artifacts (index.wasm and shim.mjs) to another folder and run from there, still the same issue. I'll try installing globally with npm instead.

Just tried and using npm install -g works while yarn global add doesn't. Definitely still an issue but I'd take this as a workaround.

commented

Same here, also using Yarn (1.22.19) - removing wrangler from devDependencies fixed it for me as well

commented

I've made a minimalistic repro here: valeriangalliat/miniflare-wrangler-conflict-repro#1

Looks like some dependency conflict between miniflare and wrangler

Maybe on a project that depends on wrangler it might be best to run wrangler dev --local instead of using Miniflare directly to avoid conflicts

I got something similar, yet when I tried to write tests in a project that didn't have one yet (it all works on Cloudflare)

I narrowed the problem down to this line:

input = webidl.converters.RequestInfo(input)

https://github.com/nodejs/undici/pull/1507/files#diff-a3765b1f356bee10fc89a5e224c8a83f131e9ffeafc7d99976499b31a99125b4R50

It invokes those:

// https://fetch.spec.whatwg.org/#requestinfo
 webidl.converters.RequestInfo = function (V) {
   if (typeof V === 'string') {
     return webidl.converters.USVString(V)
   }

   if (V instanceof Request) {
     return webidl.converters.Request(V)
   }

   return webidl.converters.USVString(V)
 }

https://github.com/nodejs/undici/pull/1507/files#diff-a3765b1f356bee10fc89a5e224c8a83f131e9ffeafc7d99976499b31a99125b4R822-R833

This approach seems just fine, right?
But Request used as global in worker code does not pass the V instanceof Request test which makes it fall back to webidl.converters.USVString which deep down is

nodeUtil.toUSVString || ((val) => `${val}`)

https://github.com/nodejs/undici/blob/f0271d46cbdc47faebfc28579b54431292e09087/lib/core/util.js#L421

"Request" coming to webidl.converters.RequestInfo has the following keys:

[
  'body',    'bodyUsed',
  'headers', 'cf',
  'signal',  'redirect',
  'url',     'method'
]

On trace it's

  › Request (node_modules/@miniflare/cache/node_modules/@miniflare/core/src/standards/http.ts:466:13)

super(new BaseRequest(input, init));

where BaseRequest is Request from undici:

import {
  Request as BaseRequest,
  // ...
} from "undici";

import {
Request as BaseRequest,
RequestInfo as BaseRequestInfo,
RequestInit as BaseRequestInit,
Response as BaseResponse,
ResponseInit as BaseResponseInit,
BodyInit,
Dispatcher,
File,
FormData,
Headers,
MockAgent,
RequestRedirect,
ResponseRedirectStatus,
fetch as baseFetch,
getGlobalDispatcher,
} from "undici";

If I'm not mistaken the problem (at least mine) is somewhere around those lines, which consciously try to avoid what - in my case - happens:

if (input instanceof BaseRequest && !init) {
    // For cloning
    super(input);
} else {
    // Don't pass our strange hybrid Request to undici
    if (input instanceof Request) input = input[_kInner];

if (input instanceof BaseRequest && !init) {
// For cloning
super(input);
} else {
// Don't pass our strange hybrid Request to undici
if (input instanceof Request) input = input[_kInner];

The problem is that what comes is not instanceof BaseRequest where it structurally looks like one.

If I try to alter the class Request in undici for debugging (by adding some new own property) I get that property there. Yet it still is not instance of BaseRequest.

What I checked already is that I have just one undici installed (i.e. it's not a problem that in one place it's taken from mode_modules/undici and elsewhre it's from mode_modules/*/node_modules/undici).

I focused on normaliseRequest

function normaliseRequest(req: RequestInfo): BaseRequest | Request {

as in my case it's on a trace (problem starts at cache.match). It reports req is neither undici nor @miniflare/core Request where during debugging it looks like its undici request.

At this point I'm leaving it, but maybe it will spark some ideas

Hey! 👋 Thanks for raising this, and apologies for the delayed response. I'm going to close this issue, as it should be fixed in Miniflare 3, which uses the same workerd runtime as production.