Skip to content

Remote form with .for() duplicate requests exponentially #14546

@bhuynhdev

Description

@bhuynhdev

Describe the bug

When I have multiple forms on the same page that submits to the same Remote function, Svelte recommends me to use a form.for(key) to distinguish between difference form instances (Don't seem to see docs for this anywhere, but the message is in console.log).

Uncaught error: A form object can only be attached to a single `<form>` element.
To create multiple instances, use `updateScore.for(key)

However, using .for() duplicates my request exponentially. First submit sends 1 requests, 2nd submit sends 2 requests, 3rd submits send 4 requests, 4th submit sends 8 requests, and so on...

What strange is that if I remove the .for() part, the Remote form looks to work like normal again.

Reproduction

Here is a Github reproduction repo: https://github.com/bhuynhdev/sveltekit-issue-14546
Here is a SvelteLab link with same content: https://www.sveltelab.dev/gpq6890y483k245?files=.%2Fsrc%2Froutes%2F%2Bpage.svelte

The reproduction step is simple:

  1. Create new project with npx sv create my-app
  2. Install valibot: npm install valibot
  3. Change svelte.config.js to include experimental features
import adapter from '@sveltejs/adapter-auto';
import { vitePreprocess } from '@sveltejs/vite-plugin-svelte';

const config = {
	preprocess: vitePreprocess(),
	compilerOptions: {
		experimental: {
			async: true
		},
	},
	kit: {
		adapter: adapter(),
		experimental: {
      remoteFunctions: true
    },
	},
};

export default config;
  1. Create routes/data.remote.js with following content:
import * as v from 'valibot'
import { form, query } from '$app/server'
let SCORE = {
  "amy": 1,
	// "bob": 2,
};

export const listScore = query(async () => {
  const dataAsPromise = await new Promise(resolve => resolve(Object.entries(SCORE)))
  return dataAsPromise
})

export const updateScore = form(
	v.object({name: v.picklist(Object.keys(SCORE))}),
  async (form) => {
    SCORE[form.name] = Number(SCORE[form.name]) + 1
    await listScore().refresh()
  }
)
  1. Update page.svelte to following content:
<script>
  import { listScore, updateScore } from "./data.remote";
  const score = listScore();
</script>

<div>
  <pre>{JSON.stringify(score.current, null, 2)}</pre>
  {#each score.current || [] as [name, _], i (name)}
    <!-- enhance to prevent form reset and potentially do other thing like show toast -->
    <form
      {...updateScore.for(name).enhance(async ({ submit }) => await submit())}
    >
      <input type="hidden" name="name" value={name} />
      <button type="submit">Submit {i}</button>
    </form>
  {/each}
</div>
  1. Run the page with npm run dev
  2. Try clicking the Submit button multiple time on http://localhost:5173

Logs

System Info

System:
    OS: Linux 6.6 Ubuntu 24.04.2 LTS 24.04.2 LTS (Noble Numbat)
    CPU: (32) x64 13th Gen Intel(R) Core(TM) i9-13900HX
    Memory: 13.50 GB / 15.46 GB
    Container: Yes
    Shell: 5.2.21 - /bin/bash
  Binaries:
    Node: 22.17.0 - ~/.local/share/mise/installs/node/22.17.0/bin/node
    npm: 10.9.2 - ~/.local/share/mise/installs/node/22.17.0/bin/npm
    pnpm: 10.15.1 - ~/.local/share/pnpm/pnpm
  npmPackages:
    @sveltejs/adapter-auto: ^6.0.0 => 6.1.0
    @sveltejs/kit: ^2.22.0 => 2.43.5
    @sveltejs/vite-plugin-svelte: ^6.0.0 => 6.2.1
    svelte: ^5.0.0 => 5.39.6
    vite: ^7.0.4 => 7.1.7

Severity

blocking an upgrade

Additional Information

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions