Redwood v4.0 and Clerk.dev "Cannot render component as a sessions already exists. Redirecting to the home url""

Hi Redwooders.

I’ve recently upgraded to Redwood v4.0, which I have to say was seamless.

I’m using Clerk.dev for my authentication. However, what with the auth changes on Redwood’s side, I’m now getting some odd sign-in / authentication / redirection oddities.

Basically, when I sign in, I get 47 warnings of:

clerk.browser.js:2 Cannot render the component as a session already exists and single session mode is enabled. Redirecting to the home url.

Is anyone else running into this since the Redwood auth changes in 4.0?

I reached out to Clerk and apparently that error happens when you’re trying to render a SignIn component when there’s already a session active.

Hey @james, glad the upgrade was easy, and thanks reporting this! I was able to reproduce the warning by trying to call logIn from the useAuth hook after signing up. Every time I clicked the log in button (attached to logIn), I’d get the warning. It sounds like you’re using Clerk’s UI components? (Is that right?) If you could share some of your project’s details, especially related to what’s rendering what (the navigations and redirects you mentioned), we could help. Some sort of GitHub repo with an example would be ideal if that’s not too much to ask

1 Like

Just wanted to +1 this, we use Redwood with Clerk’s UI components and are seeing the same warning. We’re also seeing a possibly-related issue where the page flickers on login or resuming the session. It looks like the page is redirecting between the home page and the sign-in page repeatedly for a few seconds before the redirect succeeds. In other testing, it appears the roles are not getting loaded correctly the first few times the redirect occurs.

This is my Routes.tsx:

<Router useAuth={useAuth}>
      <Route path="/sign-up" page={SignUpPage} name="signUp" />
      <Route path="/sign-in" page={SignInPage} name="signIn" />
      <Set
        wrap={GeneralLayout}
        private
        unauthenticated="signIn"
        roles={['ADMIN', 'MEMBER', 'SUPER_ADMIN']}
      >
        <SelectDateProvider>
          <Route path="/" page={SchedulerPage} name="home" />
        </SelectDateProvider>
<!-- there are some other routes in this set that aren't relevant to the login flow -->
</Set>

      <Route notfound page={NotFoundPage} />
      <Set wrap={ParentLayout} unauthenticated="signIn" roles="GUEST">
        <Route path="/parentHome" page={ParentHomePage} name="parentHome" />
      </Set>
    </Router>

I’m happy to share any other details that would be helpful–I’m trying to fix the flickering issue before we upgrade to v4.0.

Hey @asher-eastham, I’ve followed up with Clerk about the change. It looks like it was a recent one on their part here:

The part I’m confused about is, I’m not sure if Clerk is trying to say “don’t do this”, or if they’re saying “we’re helping you out by redirecting the user for you”. In the latter sense this seems like a feature, but I’m also not sure what the behavior was before. It doesn’t look like these warnings appear in production unless you’re seeing them there, but I’m also assuming you wouldn’t have deployed without solving this, so scratch that!

Let me try setting up a little example that matches your Routes file and I’ll see if I can get it to act up. If not I’ll follow up and ask for more details.

1 Like

@asher-eastham. This is exactly the problem that I’m having too. It flickers.

I’ve managed to solve this by doing some custom logic. But it was working out-of-the-box before.

Hey - cofounder of Clerk here

This message was intended to be informational. We used to have the opposite problem of developers wondering why they were redirected instead of being displayed a <SignIn/> component.

Needless to say, we swung too far the other direction.

The language will be updated, and the usage of console.warn will be replaced with console.info.

All that said, the mention of a flicker and 47 warnings is surprising and concerning. Can you please share any information that would help us repro?

What Redwood version and what Clerk version is in your package.json? If there’s a URL we can visit to see it, or if anyone has a public codebase it would be much appreciated as we work to reproduce.

2 Likes

Hey @colinclerk , thanks for chiming in.

Here are the Redwood and Clerk versions from our package.json:

web side:

    "@clerk/clerk-react": "^4.9.0",
    "@redwoodjs/auth-clerk-web": "4.0.1",
    "@redwoodjs/forms": "4.0.1",
    "@redwoodjs/router": "4.0.1",
    "@redwoodjs/web": "4.0.1",

api side:

    "@clerk/clerk-sdk-node": "4.2.0",
    "@redwoodjs/api": "4.0.1",
    "@redwoodjs/auth-clerk-api": "4.0.1",
    "@redwoodjs/graphql-server": "4.0.1",

devDependencies in base project:

    "@redwoodjs/auth-clerk-setup": "4.0.1",
    "@redwoodjs/core": "4.0.1",

If you can’t find a public codebase, I can set you up with a login to a URL that reproduces the flicker if you DM me.

Just wanted to update saying I can reproduce this pretty easily, thanks for the route structure @asher-eastham.

I’ll update this repo with more information in the README, but if you throw your Clerk keys in the .env file (which you may have to make), and start the dev server, the issue will become apparent after signing in.

Using Replay makes the problem even easier to see… the ClerkProvider in web/src/auth.tsx is rendering 26 times! I’m stepping through now to try to see why.

1 Like

@james, @asher-eastham, while I’ve been trying to fix this with the Clerk team, I want to relay a workaround we discovered. I should say that we’re a bit hesitant to recommend it since we don’t want there to be even more churn for you, but I’ll relay it and let you decide.

Simply, in web/src/auth.tsx move the ClerkLoaded component up:

 export const AuthProvider = ({ children }: Props) => {
   // ...
   return (
     <ClerkProvider {...clerkOptions} navigate={(to) => navigate(to)}>
+      <ClerkLoaded>
         <ClerkRwAuthProvider>
-          <ClerkLoaded>{children}</ClerkLoaded>
+          {children}
           <ClerkStatusUpdater />
         </ClerkRwAuthProvider>
+      </ClerkLoaded>
     </ClerkProvider>
   )
 }

This has resolved the issue in the reproduction I’ve set up. It may be worth trying it and see if it resolves it for you, just as a data point, even if you don’t go with it. Thanks!

1 Like

@dom

On my local build with that workaround, I don’t see the flicker if I sign in as a super admin user (one of the roles allowed in the first set), but I still see the flicker if I sign in as a guest user (so I’m unauthenticated for the first set).

Thanks @asher-eastham! I think I just got a complete grasp of the problem and have a WIP solution here; next steps are getting feedback from @Tobbe and the Clerk team.

@dom This worked for me. Brilliant.

I no longer see the app flickering on sign-in, nor do I see the browser’s current URL change when I hard-refresh a page after signing-in.

Before, I’d see the sign-in form flicker and the URL change to be the route for unauthenticated users. Almost like there was a disconnect between Clerk’s currentUser and Redwood’s currentUser.

As a side-note, I haven’t seen this level of personal help from any other JavaScript framework before. Huge props to yourself @dom and for @mojombo for clearly building an excellent team. It’s this hyper focused, dedicated support that developers love and will keep them in the Redwood Ecosystem.

1 Like

@james, @asher-eastham we just released v4.1.3, which includes the official patch for this bug:

There’s one manual change we recommend making, and that’s getting rid of <ClerkLoaded> all together in the web/src/auth.tsx file:

 export const AuthProvider = ({ children }: Props) => {

   // ...

   return (
     <ClerkProvider {...clerkOptions} navigate={(to) => navigate(to)}>
       <ClerkRwAuthProvider>
-        <ClerkLoaded>{children}</ClerkLoaded>
+        {children}
         <ClerkStatusUpdater />
       </ClerkRwAuthProvider>
     </ClerkProvider>
   )
 }

As a workaround, we recommended moving <ClerkLoaded> up, so it may seem odd that we’re now recommending you remove it completely. The reason is that <ClerkLoaded> blocks rendering till Clerk has loaded, which isn’t desirable since you may have routes that don’t require auth. The router has built-in support for waiting for pages that need auth loaded via the whileLoadingAuth prop. The AuthProvider returned by createAuth from @redwoodjs/auth-clerk-web now knows how to track when Clerk has loaded so that you can stay within Redwood’s API.

@james @asher-eastham unrelated to this issue, but I just released v4.2.0 which includes a security fix for the getCurrentUser function, and a codemod for it. Have a look at the release notes here and let me know if you have any questions or need any help!

1 Like