Search code examples
apollo-clientautomatic-persisted-queries

TypeError [ERR_INVALID_ARG_TYPE]: The "filename" argument must be of type string or an instance of URL. Received an instance of URL


I'm getting this very weird error trying to use Apollo persisted queries link, as instructed here, and I'm very confused of what it means, since if 'instance of URL' is a valid type and that function is receiving it like that, it shouldn't be a type error.

My link looks like this:

const httpLink = new HttpLink({
  uri: apiUri,
  fetchOptions: {
    agent: new Agent({ keepAlive: true }),
    next: {
      revalidate: 300,
    },
  },
})

const timeoutLink = new ApolloLinkTimeout(15_000)

const errorLink = onError(({ graphQLErrors, networkError, operation }) => {
  if (graphQLErrors)
    graphQLErrors.forEach(({ message, locations, path }) =>
      log.error(
        `[GraphQL error]: Message: ${message}, Location: ${JSON.stringify(
          locations
        )}, Path: ${path}, operation: ${operation.operationName}`
      )
    )
  if (networkError) {
    if (networkError.message.includes("Timeout exceeded")) {
      log.error(`Timeout exceeded Operation Name: ${operation.operationName}`)
    } else {
      log.error(
        `[Network error]: ${networkError}, operation: ${operation.operationName}`
      )
    }
  }
})

const persistedQueriesLink = createPersistedQueryLink({ sha256 })

const links = process.env.VERCEL_ENV
  ? [errorLink, timeoutLink, persistedQueriesLink, httpLink]
  : [errorLink, persistedQueriesLink, httpLink]

export const apolloLink = ApolloLink.from(links)

Solution

  • This error seems to origin from a call in crypto-hash:

    const threadFilePath = new URL('thread.js', import.meta.url);
    new Worker(threadFilePath);
    

    This probably causes problems with esbuild in the Next.js toolchain.

    For what it's worth, you don't need an external package to create a hash, so I'd recommend you replace that external sha256 function with node's crpyto functionality:

    import crypto from "node:crypto";
    function sha256(data) {
      const hash = crypto.createHash("sha256");
      hash.update(data);
      return hash.digest("hex");
    }