Skip to content
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

Named Form Action executes twice and fails with TypeError: The body has already been consumed. for await request.formData() #11663

Closed
ShriPunta opened this issue Jan 18, 2024 · 7 comments

Comments

@ShriPunta
Copy link

ShriPunta commented Jan 18, 2024

Describe the bug

I am using a named action on the route /connections/new which has a form with action ?/getAuthURL.
The method:

export const actions = {
  getAuthURL: async ({ request, locals, cookies }) => {
    const values = await request.formData();
    const loginType: FormDataEntryValue | null = values.get('loginType');
    const apiVersion: FormDataEntryValue | null = values.get('apiVersion');
.
.  // `urlToRespond` is generated by Salesforce connected app authorization
.
    redirect(303, urlToRespond)
    
    // I even tried to use a simple object return, but it still fails.
   /*
   return {
      redirectUrl: urlToRespond
    }
   */
}

This is the +page.svelte code

<script lang="ts">
.. // Basic variables for the form fields
..
</script>
<form
		method="POST"
		action="?/getAuthURL"
		class="shadow-md rounded px-8 pt-6 pb-8 mb-4 self-center"
		in:fly={{ y: 20 }}
		out:slide
	>
		.....
		<button type="submit">
			Login to Salesforce
		</button>
	</form>

I have used the VSCode Javascript Debug Terminal to go step through each line of the method in +page.server.ts when I "Submit" the form from +page.svelte.
The request comes through properly and goes through my hooks.server.ts smoothly. It executes the const values = await request.formData(); and generates the values correctly. It goes till the end of the method perfectly and even populates urlToRespond.
I made sure by checking the request.bodyUsedfunction is ONLY BEING SET when we read the await request.formData() in the first line.
BUT THEN weirdly, after the last line, the flow of the program JUMPS backs to the first line, to const values = await request.formData();, where it tries to read formData again and then fails with
TypeError: The body has already been consumed.

I made sure that there was no recursion in the program and there weren't MULTIPLE requests coming from the client side as well.

??? What the hell is happening? how is the control of flow jumping back to the start of the method??

Workaround

The following feels unnecessary and is not the cleanest way, but cloning the request worked.
However while stepping through the function with a debugger, I saw the named action method got executed twice

    const clonedRequest = request.clone();
    const values = await clonedRequest.formData();

Reproduction

I have tried to simulate it here

But i am not able to reproduce it.

Here are screenshots to show the method block executing successfully from 1st line to last and then erratically jumping back to the first line.
1st time hitting the submit function:
image

Successfully going to the last line of the method and populating the urlToRespond variable
image

But then going back to the first line and RESETTING all the local variables??????
image

and then the failure

image

Logs

TypeError: The body has already been consumed.
    at consumeBody (node:internal/deps/undici/undici:6405:19)
    at consumeBody.next (<anonymous>)
    at Request.formData (node:internal/deps/undici/undici:6494:32)
    at getAuthURL (/Users/shri/Documents/Development/ShriPuntaGitHub/SFToolsWSvelteKit/src/routes/connections/new/+page.server.ts:12:34)
    at call_action (/Users/shri/Documents/Development/ShriPuntaGitHub/SFToolsWSvelteKit/node_modules/.pnpm/@sveltejs+kit@2.0.0_@sveltejs+vite-plugin-svelte@3.0.0_svelte@4.2.7_vite@5.0.3/node_modules/@sveltejs/kit/src/runtime/server/page/actions.js:239:9)
    at Module.handle_action_json_request (/Users/shri/Documents/Development/ShriPuntaGitHub/SFToolsWSvelteKit/node_modules/.pnpm/@sveltejs+kit@2.0.0_@sveltejs+vite-plugin-svelte@3.0.0_svelte@4.2.7_vite@5.0.3/node_modules/@sveltejs/kit/src/runtime/server/page/actions.js:51:22)
    at Module.render_page (/Users/shri/Documents/Development/ShriPuntaGitHub/SFToolsWSvelteKit/node_modules/.pnpm/@sveltejs+kit@2.0.0_@sveltejs+vite-plugin-svelte@3.0.0_svelte@4.2.7_vite@5.0.3/node_modules/@sveltejs/kit/src/runtime/server/page/index.js:43:10)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async resolve (/Users/shri/Documents/Development/ShriPuntaGitHub/SFToolsWSvelteKit/node_modules/.pnpm/@sveltejs+kit@2.0.0_@sveltejs+vite-plugin-svelte@3.0.0_svelte@4.2.7_vite@5.0.3/node_modules/@sveltejs/kit/src/runtime/server/respond.js:409:18)
    at async Module.respond (/Users/shri/Documents/Development/ShriPuntaGitHub/SFToolsWSvelteKit/node_modules/.pnpm/@sveltejs+kit@2.0.0_@sveltejs+vite-plugin-svelte@3.0.0_svelte@4.2.7_vite@5.0.3/node_modules/@sveltejs/kit/src/runtime/server/respond.js:282:20)


### System Info

```Shell
System:
    OS: macOS 14.2.1
    CPU: (8) arm64 Apple M1 Pro
    Memory: 371.97 MB / 32.00 GB
    Shell: 5.9 - /bin/zsh
  Binaries:
    Node: 20.0.0 - ~/.nvm/versions/node/v20.0.0/bin/node
    Yarn: 1.22.19 - ~/.nvm/versions/node/v20.0.0/bin/yarn
    npm: 9.6.6 - ~/.nvm/versions/node/v20.0.0/bin/npm
    pnpm: 8.14.0 - ~/.nvm/versions/node/v20.0.0/bin/pnpm
  Browsers:
    Chrome: 120.0.6099.216
    Safari: 17.2.1
  npmPackages:
    @sveltejs/adapter-auto: ^3.0.0 => 3.0.0 
    @sveltejs/kit: ^2.0.0 => 2.0.0 
    @sveltejs/vite-plugin-svelte: ^3.0.0 => 3.0.0 
    svelte: ^4.2.7 => 4.2.7 
    vite: ^5.0.3 => 5.0.3 


### Severity

serious, but i can work around it

### Additional Information

_No response_
@ShriPunta ShriPunta changed the title Named Form Action weirdly failing with TypeError: The body has already been consumed. for await request.formData() Named Form Action executes twice and fails with TypeError: The body has already been consumed. for await request.formData() Jan 18, 2024
@ShriPunta
Copy link
Author

ShriPunta commented Jan 18, 2024

I have tried the following:

  • using the default action instead of a named action
  • removing the action attribute on form and using the button OUTSIDE the form element and using the formaction attribute on the button
  • using a use:enhance custom SubmitFunction to submit the form
  • using an id attribute on the form and moving the button outside form and setting the form attribute on button to "${formId}".
  • commented everything in the default action and only kept the following lines, and it still fails
const vals = await request.formData();
redirect(303, 'connections/close');

@ShriPunta
Copy link
Author

I am calling invalidateAll on the client side and I can see that load function is being called twice as well. Why is this happening?

image

image

@gterras
Copy link

gterras commented Jan 19, 2024

Hi,

Unfortunately invalidation is broken in Sveltekit, so are many related features, see :

#11446
#10209
#10123
#10457
#10359

Sadly you will most likely get no answer from maintainers as no one seem to know how to fix this.

@eltigerchino
Copy link
Member

Please provide a working minimal reproduction that reproduces the issue.

@benmccann
Copy link
Member

#11870 just fixed most of the reported issues with invalidation, so can you test to see if you're still having issues with 2.5.1?

@ShriPunta
Copy link
Author

Hi @benmccann I updated the SvelteKit version but still facing the same issue
image

@ShriPunta
Copy link
Author

ShriPunta commented Mar 22, 2024

Thank you so much to @fehnomenal who help me fix my issue. It was a bug in my hooks.server.ts.

I am using a sequence function to do two operations for the authenticated route.
I was returning all resolve(event) statements, but i did not add an await for my sequence method call.

This caused the requests to be done one after another. I am not sure how does it work internally, but adding an await for my sequence function call worked.
Thank you again to @fehnomenal

More details are here: #6800 (comment)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants