Skip to content

[🐞] Error: Actions can not be invoked within the server during SSR. #5874

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
engineersamwell opened this issue Feb 21, 2024 · 4 comments · May be fixed by #7606
Open

[🐞] Error: Actions can not be invoked within the server during SSR. #5874

engineersamwell opened this issue Feb 21, 2024 · 4 comments · May be fixed by #7606
Assignees
Labels
COMMUNITY: PR is welcomed We think it's a good feature to have but would love for the community to help with the PR for it COMP: DX Developer Experience related issue COMP: qwik-city TYPE: enhancement New feature or request

Comments

@engineersamwell
Copy link

Which component is affected?

Qwik Runtime

Describe the bug

When attempting to vitest a component that invokes a routeAction$ I'm getting the error:

Error: Actions can not be invoked within the server during SSR.
Action.run() can only be called on the browser, for example when a user clicks a button, or submits a form.
    at Proxy.routeActionQrl_action_submit_A5bZC7WO00A

I thought that vitest would render using the node environment and thus SSR and I could mock out the HTTP API call that my action is ultimately making. This is not the case though and I can't find any good documentation on how to do this.

  test('Should successfully remove users', async () => {
    const Wrapper = component$(() => {
      const removeDialogRef = useSignal<HTMLElement>();
      const onClose$ = $(onCloseSpy);

      return (
        <QwikCityMockProvider>
          <RemoveUsers
            ref={removeDialogRef}
            selectedUsers={selectedUsers}
            close={onClose$}
          />
        </QwikCityMockProvider>
      );
    });

    const { render, userEvent } = await createDOM();
    await render(<Wrapper />);
    await userEvent('.vi-submit-remove', 'click');
  });

Where within the RemoveUsers component it calls action.submit(data as unknown as FormData) which ultimately makes an HTTP POST call.

Reproduction

http://no.repro.url

Steps to reproduce

No response

System Info

System:
    OS: macOS 14.3.1
    CPU: (20) arm64 Apple M1 Ultra
    Memory: 212.80 MB / 64.00 GB
    Shell: 5.9 - /bin/zsh
  Binaries:
    Node: 20.10.0 - ~/.nvm/versions/node/v20.10.0/bin/node
    npm: 10.2.3 - ~/.nvm/versions/node/v20.10.0/bin/npm
    bun: 1.0.7 - /opt/homebrew/bin/bun
  Browsers:
    Chrome: 113.0.5672.126
    Safari: 17.3.1
  npmPackages:
    @builder.io/qwik: ^1.4.3 => 1.4.3
    @builder.io/qwik-auth: 0.1.3 => 0.1.3
    @builder.io/qwik-city: ^1.4.3 => 1.4.3
    @builder.io/qwik-react: 0.5.0 => 0.5.0
    undici: 5.28.2 => 5.28.2
    vite: 5.0.12 => 5.0.12

Additional Information

No response

@engineersamwell engineersamwell added STATUS-1: needs triage New issue which needs to be triaged TYPE: bug Something isn't working labels Feb 21, 2024
@wmertens
Copy link
Member

Hmm, so the QwikCityMockProvider should somehow make it so that actions run locally? Or should they be mocked entirely?

Sounds feasible but needs a good think about the API. PRs very welcome.

@wmertens wmertens added TYPE: enhancement New feature or request COMP: qwik-city COMP: DX Developer Experience related issue COMMUNITY: PR is welcomed We think it's a good feature to have but would love for the community to help with the PR for it and removed TYPE: bug Something isn't working STATUS-1: needs triage New issue which needs to be triaged labels Feb 28, 2024
@engineersamwell
Copy link
Author

That's correct, in this context I'd want to mock the fetch calls for testing, however that doesn't mean there isn't a scenario in which one would want the action to run as normal as well.

@engineersamwell
Copy link
Author

@wmertens Help me understand the QwikCityMockProvider. If I look at https://github.com/QwikDev/qwik/blob/main/packages/qwik-city/runtime/src/qwik-city-component.tsx#L130 and https://github.com/QwikDev/qwik/blob/main/packages/qwik-city/runtime/src/qwik-city-component.tsx#L578 the actionState is added as a context so theoretically actions should be able to be called. If I look at the error itself it happens here: https://github.com/QwikDev/qwik/blob/main/packages/qwik-city/runtime/src/server-functions.ts#L90 and I assume the error is thrown because HTMLFormElement is not available from a SSR based action call.

Can you provide more thoughts on how this would be implemented? I'm happy to do some work here but I need to understand what exactly is missing and what needs to be either mocked out or filled it, in isn't exactly clear.

The huge windfall here would be the ability to rapidly test one's app with mocked data. The speed we could test if this was in place would be an order of magnitude faster vs cypress or playwright or any of the e2e testing libraries.

LogProphet added a commit to LogProphet/qwik that referenced this issue May 16, 2025
Previously the SSR‐guard in `server-functions.ts` unconditionally threw
whenever `isServer` was true,
which blocked invocation of `routeAction$` under Vitest+JSDOM (and the
QwikCityMockProvider) in user tests.

Now we narrow the guard to:

if (isServer && typeof window === 'undefined') {
  throw …;
}

After this fix:

- True SSR(no 'window') still throws an error as beforev
- JSDOM/Vitest tests(and browsers) have a global 'window', do not throw
the error, and returns a promise

This will unblock testing of actions in JSDOM environments without
impacting real SSR safety

Closes QwikDev#5874
@LogProphet
Copy link
Contributor

@wmertens I believe i've found a creative way to resolve this issue. I have a PR out for this (#7606 ). Can this issue be assigned to me?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
COMMUNITY: PR is welcomed We think it's a good feature to have but would love for the community to help with the PR for it COMP: DX Developer Experience related issue COMP: qwik-city TYPE: enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants