A
arktype5mo ago
PIat

must be an instance of FormData (was object)

Hello! This code:
const formData = await request.clone().formData();

const formSchema = type({
name: 'string>0',
surname: 'string>0'
})

const parseForm = type('parse.formData').pipe(formSchema)

const formResult = parseForm(formData)
const formData = await request.clone().formData();

const formSchema = type({
name: 'string>0',
surname: 'string>0'
})

const parseForm = type('parse.formData').pipe(formSchema)

const formResult = parseForm(formData)
Throws following error:
must be an instance of FormData (was object)
must be an instance of FormData (was object)
However, formData is instanceof FormData and the log also says it's FormData:
ArkError {
input: {
code: 'proto',
description: 'an instance of FormData',
proto: [class FormData]
},
' arkKind': 'error',
path: [],
data: FormData { name: 'Plat', surname: '' },
...
ArkError {
input: {
code: 'proto',
description: 'an instance of FormData',
proto: [class FormData]
},
' arkKind': 'error',
path: [],
data: FormData { name: 'Plat', surname: '' },
...
What am I doing wrong?
27 Replies
ssalbdivad
ssalbdivad5mo ago
What did you see that makes you sure it's an instance of FormData? Try just creating it from new FormData() instead and see if that works
PIat
PIatOP5mo ago
I did console.log(formData)
ssalbdivad
ssalbdivad5mo ago
Did you try it with:
const formData = new FormData()
const formData = new FormData()
I need something I can actually repro
PIat
PIatOP5mo ago
This throws the same error
const formSchema = type({
name: 'string>0',
surname: 'string>0'
})

const parseForm = type('parse.formData').pipe(formSchema)

const data = new FormData()

data.append('name', 'Plat')
data.append('surname', '')

const formResult = parseForm(data)
const formSchema = type({
name: 'string>0',
surname: 'string>0'
})

const parseForm = type('parse.formData').pipe(formSchema)

const data = new FormData()

data.append('name', 'Plat')
data.append('surname', '')

const formResult = parseForm(data)
ssalbdivad
ssalbdivad5mo ago
Works for me
No description
PIat
PIatOP5mo ago
Aw :( Well, parse.number works inside of this package, but now it's formData
ssalbdivad
ssalbdivad5mo ago
I mean it would be one thing if it was unresolvable like before but you're saying this time that it's not an instanceof FormData but that's not the error I get
PIat
PIatOP5mo ago
No description
No description
ssalbdivad
ssalbdivad5mo ago
Can you just show me the error message .toString() like I did?
PIat
PIatOP5mo ago
No description
ssalbdivad
ssalbdivad5mo ago
You get that even if you just pass new FormData() directly to the validator?
PIat
PIatOP5mo ago
Yes, as per the first picture I'm on Node 20.14.0 Typescript 5.5.3 Arktype 2.0.0-beta.5
ssalbdivad
ssalbdivad5mo ago
May as well try beta.6 I can't repro it with those exact versions
PIat
PIatOP5mo ago
I tried the latest version, also installed it at the root of the workspace, so that there would only be one installation of Arktype, still the same error
ssalbdivad
ssalbdivad5mo ago
I tried my best to repro it you will have to link me a repo/branch I can clone
PIat
PIatOP5mo ago
I think I found where the issue lies. When using Arktype in Vite directly, it works fine, but when I was running it through a server file, which included this code, which installs undici:
import { installGlobals } from '@remix-run/node'

installGlobals({
nativeFetch: true,
})
import { installGlobals } from '@remix-run/node'

installGlobals({
nativeFetch: true,
})
it must've been setting a polyfilled FormData on globalThis. Hence it had the same name but wasn't seen as the same object, since Arktype is in a separate package. Me again with the formdata 😆 When running this on the client, everything works fine:
const formType = type({
intent: "'profile'",
name: 'string>0',
surname: 'string>4',
}).or({
intent: "'private'",
password: 'string>0',
})

formType.assert({
intent: 'profile',
name: 'Plat',
surname: 'PlatPlat',
}),
const formType = type({
intent: "'profile'",
name: 'string>0',
surname: 'string>4',
}).or({
intent: "'private'",
password: 'string>0',
})

formType.assert({
intent: 'profile',
name: 'Plat',
surname: 'PlatPlat',
}),
But on the server:
const parseForm = type('parse.formData').pipe(formSchema)

const formData = isFormData(request)
? request
: await request.clone().formData()

const formResult = formData && parseForm(formData)
const parseForm = type('parse.formData').pipe(formSchema)

const formData = isFormData(request)
? request
: await request.clone().formData()

const formResult = formData && parseForm(formData)
I get this error:
intent must be "private" or "profile" (was "profile")
intent must be "private" or "profile" (was "profile")
What could be the issue?
ssalbdivad
ssalbdivad5mo ago
Hmm not sure that doesn't make any sense. You could introspect the data a bit to see what it means by was "profile", but the fact that it's only happening on the server makes me thing it's some nonsense remix is doing like it was the last time.
PIat
PIatOP5mo ago
Must be
FormData {
name: '"Plat"',
surname: '"PlatPlat"',
intent: '"profile"'
}
FormData {
name: '"Plat"',
surname: '"PlatPlat"',
intent: '"profile"'
}
I guess the quotes are staying there?
data: { name: '"Plat"', surname: '"PlatPlat"', intent: '"profile"' },
data: { name: '"Plat"', surname: '"PlatPlat"', intent: '"profile"' },
But shouldn't that be handled by parse.formData?
ssalbdivad
ssalbdivad5mo ago
Maybe the polyfilled formdata is wrong
PIat
PIatOP5mo ago
Yes, the issue is definitely on the Remix side. But how come the error had the quotation marks around everything?
ssalbdivad
ssalbdivad5mo ago
I don't have enough context from what you posted to understand haha
PIat
PIatOP5mo ago
And not double quotes
ssalbdivad
ssalbdivad5mo ago
I'd say though if it works on the client and there was something weird going on on the server, probably not worth digging into that much
PIat
PIatOP5mo ago
No, I mean the wrong value that was passed was "profile" instead of profile. But the error only showed one (") quotation marks: intent must be "private" or "profile" (was "profile")
ssalbdivad
ssalbdivad5mo ago
Hmm yeah maybe there is an issue there
ssalbdivad
ssalbdivad5mo ago
Yep just added a new test case for this, thanks! Between multiple kinds of precompilation and undiscriminated and discriminated unions there are so many places to get error messages right 🫠
No description
No description
PIat
PIatOP5mo ago
I can only imagine 😁
Want results from more Discord servers?
Add your server