Relay: Cryptic runtime error in relay 8.0.0 "Warning: RelayGraphQLTag: node ... unexpectedly wrapped in a function."

Created on 8 Jan 2020  路  24Comments  路  Source: facebook/relay

We've recently updated to relay 8.0.0 from 7.1.0 and are now starting to see the following error in console and while running unit tests:
console.error node_modules/relay-runtime/node_modules/fbjs/lib/warning.js:30 Warning: RelayGraphQLTag: node [Query] unexpectedly wrapped in a function.

package.json (partial)
"react-relay": "^8.0.0", "relay-runtime": "^8.0.0", "relay-test-utils": "^8.0.0", "react-relay-network-modern": "^4.4.0", "babel-plugin-relay": "^6.0.0", "relay-compiler": "^8.0.0",

Any help is appreciated!

Most helpful comment

I also encountered this issue and the root cause ended up being babel-loader's cache. Clearing the cache directory resolved this.

All 24 comments

upgrade babel-plugin-relay to v8

Thank you very much!

FYI: Just tested this with "babel-plugin-relay": "^8.0.0", still getting the same error.

flow or typescript?

try to remove all __generated__ and regenerate them

Neither. Removed the __generated__ folder and re-ran relay compiler (relay-compiler --src ./src/ --schema ./schema.graphql --artifactDirectory ./src/__generated__/relay). Same issue.

make sure all relay version are the same

yarn why react-relay
yarn why relay-runtime

is this web ou app?

can you great a repro?

check this https://github.com/relayjs/relay-examples/pull/131

=> Found "[email protected]"
=> Found "[email protected]"
=> Found "[email protected]"

This is a react webapp.

OK, so I've deleted and re-created everything. No longer see errors in console, but do see these as errors when running jest tests, so might be related to jest (24.9) and/or relay-test-utils (8.0.0).

try to remove jest cache

it looks like it is not transpiling correct

Looks like clearing the jest cache worked. Thank you again!

We're facing the same issue, tried

  • removing node_modules and yarn install again
  • check versions
  • regenerated queries

but cant' get it to work.

In addition to this, when trying to print the error, can't find the node and raises an error. We did not change anything in our queries and/or component since v7 (that works).

Uncaught TypeError: Cannot read property 'name' of undefined
    at getNode (GraphQLTag.js:32)

We use typescript, may it be an issue with relay-compiler-language-typescript?

I also encountered this issue and the root cause ended up being babel-loader's cache. Clearing the cache directory resolved this.

@kejistan indeed, got it working! Thank you very much!

This worked for our CRA-based setup:

rm -rf node_modules/.cache/
rm src/**/__generated__/*.graphql.js

We are also experiencing issues with the generated TS files, even after removing the node_modules and __generated__ the result of running the relay-compiler is the same

We're also having the exact same problem as @apuntovanini (Uncaught TypeError: Cannot read property 'name' of undefined at getNode (GraphQLTag.js:32)) and we're also using TypeScript. However, not all of our team members are encountering the issue. Clearing babel cache and compiled fragments didn't help.

cc: @perryazevedo

Clear all the caches

Babel
Watchman
Metro-bundler
Webpack
Jest
__generated__
typescript

@sibelius, I admit that it feels like a caching issue due to the fact that it's inconsistently broken, but I'm not sure what else to try. We ran the following:

# Clear __generated__
find . -name __generated__ -type d -print0|xargs -0 rm -r --
# Clear node_modules cache
rm -rf node_modules/.cache

We're not using Jest (or any other kind of testing), Watchman, or Metro bundler. TS to my knowledge doesn't cache anything.

Any other places we should be looking for caches/commands we should try running?

Try to create a repro

I've isolated the immediate cause for our issue, but I'm not sure why it's happening.

In a recent change to GraphQLTag.js, these lines were added:

if (typeof node === 'function') {
  node = (node(): ReaderFragment | ConcreteRequest);
  warning(
    false,
    'RelayGraphQLTag: node `%s` unexpectedly wrapped in a function.',
    node.kind === 'Fragment' ? node.name : node.operation.name,
  );
} else if (node.default) {
  // Support for languages that work (best) with ES6 modules, such as TypeScript.
  node = node.default;
}

The problem in our case is that node is a function that, instead of returning a node, returns an object that has a single default field that contains the node, so node.operation.name fails. Seems like the else if (node.default) is intended to catch this case, but it doesn't account for default exports returned by functions-wrapped nodes...?

Our workaround is to patch the code above by inserting if (node["default"]) node = node.default; after node = (node(): ReaderFragment | ConcreteRequest);. Then we're able to see the warnings.

I don't know enough about relay-runtime to create a repro, but I do know that this is happening for one developer on our team even after we've cleared his caches, nuked the repo and started from scratch, etc. Doesn't happen for the other devs.

This seems relevant: https://github.com/facebook/react/issues/12453#issue-308403033

I traced node back to https://github.com/facebook/relay/blob/v8.0.0/packages/react-relay/buildReactRelayContainer.js#L73. I'm guessing that for our dev and possibly others, forwardRef is returning a function. If that's the case, React needs to be upgraded and a more helpful message should be displayed. Will confirm.

EDIT: Looks like we're all running React 16.12.0, according to yarn why react. So I'm not sure why this is happening 馃檭.

EDIT 2: The plot thickens...

My previous comment was a red herring. The problem has to do with the Babel plugin. It transforms the JS AST, swapping the graphql`...` tagged template literals with their compiled counterparts inside of __generated__. Something was causing the plugin to output functions instead of the objects exported from the compiled fragments.

After looking at the Babel plugin's code, we "fixed" our problem by changing our .babelrc config from

{ plugins: [
  ["relay", { "artifactDirectory": "./app/javascript/__generated__" }]
]}

to

{ plugins: [
  ["relay", { "artifactDirectory": "./app/javascript/__generated__", "eagerESModules": true }]
]}

Only one problem: eagerESModules isn't an option that's supported by the version of the Babel plugin, 8.0.0, that we're using. It's present in master and in version 9.0.0.

We are using relay-compiler-language-typescript, but the solution proposed by @earksiinni has also fixed the Uncaught TypeError: Cannot read property 'name' of undefined at getNode issue

I upgraded Relay from v7.1.0 to v9.0.0 in a Next.js project. The error was caused by a caching issue. The solution for me was to delete the .next/cache/next-babel-loader directory.

A side note: at first I thought @earksiinni's solution to set eagerESModules to true was the fix. But I realized that changing my babel config must have busted the next-babel-loader cache to make the error go away, but it wasn't the true solution.

I was having the same problem as @earksiinni, upgrading from 7.1.0 to 9.0.0. Before finding this issue, I modified relay-runtime to dig into node["default"], which fixed the problem, but I ended up with the warning @agdt3 reported (which is how I found this issue). I'm happy to say the fix was the same: clear jest's cache. With that, I was able to back out my modification to relay-runtime. I don't think any change is needed in Babel.

I didn't even know jest had a cache, so this issue was illuminating in a couple ways. If jest doesn't invalidate the cache when it should, I can see that being an ongoing problem. But, at least I have a new thing to add to the checklist when tests go haywire.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

amccloud picture amccloud  路  3Comments

MartinDawson picture MartinDawson  路  3Comments

HsuTing picture HsuTing  路  3Comments

mike-marcacci picture mike-marcacci  路  3Comments

derekdowling picture derekdowling  路  3Comments