Remote form: Coercing checkbox values to number doesn't work
Nobody has claimed this yet.
- Dominant language
- JavaScript
- Stars
- 20.8k
- Forks
- 2.3k
- Avg merge
- 1d 16h
- Merged PRs (30d)
- 156
Description
Describe the bug
Currently the coersion of checkbox values doesn't consistently work (zod or valibot).
Given the following code:
<!-- src/routes/+page.svelte -->
<script lang="ts" module>
import * as z from 'zod'
import { buyStocks } from './stocks.remote.js'
const buyStocksSchema = z.object({
stockIds: z.array(z.coerce.number<string>()).min(1)
})
const availableStocks = [
{ id: 1, name: 'Google' },
{ id: 2, name: 'Amazon' },
{ id: 3, name: 'Netflix' },
]
</script>
<form {...buyStocks}>
<div>
{#each availableStocks as stock}
<label>
<input {...buyStocks.fields.stockIds.as('checkbox', stock.id.toString())} />
</label>
{/each}
</div>
<button type="submit">Buy</button>
</form>
// src/routes/stocks.remote.ts
import { form } from '$app/server'
export const buyStocks = form(schema, (data) => {
console.log(data) // --> [Object: null prototype] { stockIds: [ '2', '3' ], amount: 1 }
return {}
})
your validation output for stockIds will be sometimes Array<string> and sometimes Array<number>.
So far i observed the following:
- When you do a fresh start of the dev server, you'll get
Array<string> - When the dev server updates the page after editing source code, you'll get the expected
Array<number> - It seems like the issue only occurs when you import your schema from a component's <script module>
Update:
- I also tested it with valibot -> same results
- When running the preview after build, you'll get a 500 for the pages:
[500] GET /
ReferenceError: Cannot access 'schema' before initialization
at file:///home/user/kit-sandbox/.svelte-kit/output/server/chunks/remote-4yax8d.js:13:24
at ModuleJob.run (node:internal/modules/esm/module_job:329:25)
at async onImport.tracePromise.__proto__ (node:internal/modules/esm/loader:644:26)
at async Module.component (file:///home/user/kit-sandbox/.svelte-kit/output/server/nodes/2.js:5:59)
at async Promise.all (index 1)
at async render_response (file:///home/user/kit-sandbox/.svelte-kit/output/server/index.js:2014:21)
at async render_page (file:///home/user/kit-sandbox/.svelte-kit/output/server/index.js:3036:12)
at async resolve2 (file:///home/user/kit-sandbox/.svelte-kit/output/server/index.js:4239:25)
at async fn (file:///home/user/kit-sandbox/.svelte-kit/output/server/index.js:4099:16)
at async internal_respond (file:///home/user/kit-sandbox/.svelte-kit/output/server/index.js:4081:22)
So it seems like this is not entirely true (at least for now):
https://github.com/sveltejs/kit/blob/c4f28a189f04c4edddd3dd754a20581f7d59eac6/documentation/docs/20-core-concepts/60-remote-functions.md?plain=1#L549-L553
Reproduction
https://github.com/Blackwidow-sudo/kit-sandbox
- Clone the repo
- start the dev server
- submit the form with some stocks
- edit the
+page.svelteand submit the form again
Logs
[Object: null prototype] { stockIds: [ '2', '3' ] }
[Object: null prototype] { stockIds: [ '2', '3' ] }
[Object: null prototype] { stockIds: [ '2', '3' ] }
8:17:30 PM [vite] (client) hmr update /src/routes/+page.svelte
{ stockIds: [ 2, 3 ] }
System Info
System:
OS: Linux 6.6 Ubuntu 24.04.3 LTS 24.04.3 LTS (Noble Numbat)
CPU: (16) x64 AMD Ryzen 7 7700X 8-Core Processor
Memory: 12.26 GB / 15.17 GB
Container: Yes
Shell: 5.2.21 - /bin/bash
Binaries:
Node: 22.17.1 - /home/user/.local/share/pnpm/node
npm: 10.9.2 - /home/user/.local/share/pnpm/npm
pnpm: 10.14.0 - /home/user/.local/share/pnpm/pnpm
npmPackages:
@sveltejs/adapter-auto: ^6.1.0 => 6.1.1
@sveltejs/kit: ^2.43.2 => 2.46.4
@sveltejs/vite-plugin-svelte: ^6.2.0 => 6.2.1
svelte: ^5.39.5 => 5.39.11
vite: ^7.1.7 => 7.1.9
Severity
annoyance
Additional Information
No response
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the reproduction repository and compare the behavior of src/routes/+page.svelte and src/routes/stocks.remote.ts after a fresh dev start, HMR update, and preview build. Check the linked remote-functions documentation alongside the reported logs and generated error. Done means checkbox values are consistently coerced to numbers and the preview page no longer fails with the reported initialization error.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript, typescript
- Domain
- full-stack
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 42/100