erquhart
erquhartā€¢14mo ago

convex dev 400, schema error

Analyzing and deploying source code...
āœ– Error: Unable to push deployment config to <dev-url>
400 Bad Request: Error: Hit an error while pushing:
Uncaught TypeError: Cannot read properties of undefined (reading 'json')
Analyzing and deploying source code...
āœ– Error: Unable to push deployment config to <dev-url>
400 Bad Request: Error: Hit an error while pushing:
Uncaught TypeError: Cannot read properties of undefined (reading 'json')
The code it's referencing is from validator.ts - the error is specifically where v.json is being asssigned to fieldType - v is undefined:
object<T extends PropertyValidators>(schema: T): ObjectValidator<T> {
return new Validator(
{
type: "object",
value: Object.fromEntries(
Object.entries(schema).map(([k, v]) => [
k,
{ fieldType: v.json, optional: v.optional },
])
),
},
false
);
},
object<T extends PropertyValidators>(schema: T): ObjectValidator<T> {
return new Validator(
{
type: "object",
value: Object.fromEntries(
Object.entries(schema).map(([k, v]) => [
k,
{ fieldType: v.json, optional: v.optional },
])
),
},
false
);
},
I've pored over my schema and can't find any undefined values. The only place I can even think of that could cause this is maybe mispelling a table name in v.id(), but I'm not even certain that would result in undefined. Pretty stuck here, any help greatly appreciated.
22 Replies
ballingt
ballingtā€¢14mo ago
Looks like the v in map(([k, v]) is shadowing the variable
erquhart
erquhartOPā€¢14mo ago
Oh is v.json trying to reference the outer v? I'd expect every deployment to be broken though, this is in convex source - not sure why it would have limited impact
ballingt
ballingtā€¢14mo ago
oh sorry I was thinking this was your code, didn't read carefully What's your schema look like, is it possible you have an entry in there that is undefined?
erquhart
erquhartOPā€¢14mo ago
I've been troubleshooting for about an hour and am blocked due to not getting logs - I'm guessing this is running on convex's side and logs are obfuscated?
ballingt
ballingtā€¢14mo ago
If you're pushing to dev you should get logs, so if they aren't being sent down for schema evaluation that's something for us to fix
erquhart
erquhartOPā€¢14mo ago
I feely pretty certain that an undefined schema value would get blocked at the type level, as I'm not doing anything weird, no as, etc.
ballingt
ballingtā€¢14mo ago
misspelling a validator could cause this (v.object({a}) where a is undefined) but yeah agree, should get a type error
erquhart
erquhartOPā€¢14mo ago
I'm not even doing references for objects, it's all defined inline. I've checked the diff since my last successful deploy, very limited changes to objects, and they're all inline using first class validators by direct reference Is v.object() used by defineTable() to validate the whole table definition by chance? That doesn't actually change my diagnosis as my top level fields are also all by direct reference, but wanted to check
ballingt
ballingtā€¢14mo ago
if you can share the diff we might spot it, sorry for the lack of logs here. Removing one table or field at a time might get you there but sounds like you've been at this for a while. Feel free to dm
erquhart
erquhartOPā€¢14mo ago
Removing tables breaks types - if I turn off type checking will the schema eval run? trying now
ballingt
ballingtā€¢14mo ago
missed this, but yeah that makes sense
erquhart
erquhartOPā€¢14mo ago
I get the error with an empty schema šŸ˜­
ballingt
ballingtā€¢14mo ago
well that's interesting info sorry you don't have a stack trace here, that would sure help!
erquhart
erquhartOPā€¢14mo ago
I've now removed the schema file entirely, same error o_O checking if I'm using v.object() in some obscure place
ballingt
ballingtā€¢14mo ago
progress! delete everything else šŸ’£
erquhart
erquhartOPā€¢14mo ago
only used in the schema. yeah I'll keep deleting stuff
ballingt
ballingtā€¢14mo ago
you think it's v.object because that's the only place we see v.json? from just the error it could be eg a fetch response being undefined well not quite, that wouldn't run during schema push
erquhart
erquhartOPā€¢14mo ago
The stack trace in the source points to v.object() specifically It's running the object passed in to v.object() through Object.entries() and expecting the v in [k,v] to be an object Deleting all of my convex code did indeed clear the error lol I'll keep narrowing and let you know what I find
ballingt
ballingtā€¢14mo ago
so far we know we need to make logs work here, and it sounds like this stack trace does not have as much info as we'd like (is it not showing the other stack frames?) so at least we have those to fix plus whatever you find here
erquhart
erquhartOPā€¢14mo ago
The trace includes a few frames, but doesn't go outside of v.object():
400 Bad Request: Error: Hit an error while pushing:
Uncaught TypeError: Cannot read properties of undefined (reading 'json')
at <anonymous> (../../node_modules/convex/src/values/validator.ts:135:6)
at map [as map] (<anonymous>)
at object [as object] (../../node_modules/convex/src/values/validator.ts:131:12)
400 Bad Request: Error: Hit an error while pushing:
Uncaught TypeError: Cannot read properties of undefined (reading 'json')
at <anonymous> (../../node_modules/convex/src/values/validator.ts:135:6)
at map [as map] (<anonymous>)
at object [as object] (../../node_modules/convex/src/values/validator.ts:131:12)
There may be other issues, but it seems likely to be down to this: I have an oft-reused validator:
const authzValidator = v.object({
users: v.id('users'),
budgets: v.id('budgets'),
})
const authzValidator = v.object({
users: v.id('users'),
budgets: v.id('budgets'),
})
If I import this validator from another file and use it as an argument validator, I get the error. If I use it inline, no error. If I define it elsewhere in the same file and use it by reference, no error. Only errors on import. Furthermore: - I have one file per table for my db layer - some import this validator and some don't - of the ones that do, some can do so with no error, others cause the error I've tried replacing the v.id() in the validator with v.string() in case it was some kind of weird table validation reference issue, but that made no difference. Still digging. @ballingt I've gone ahead and used inline validators for every instance of this object, that solves it. Are nested objects validators not able to reference imported values? Wondering if I'm missing something. Just realized it's the weekend, please ignore until you're on working hours! Found a way - keeping the shared validator as a plain object and spreading it is the only way that doesn't produce errors. Each case below is exporting a validator and then importing and using that validator in function args.
// Fails in some cases, not sure why
export const fooBarValidator = v.object({
bar: v.string(),
})
args: {
foo: fooBarValidator,
}

// Fails at least some cases, maybe all - different error, "fooBarValidator is not a function" (it certainly is)
export const fooBarValidator = () => {
return v.object({
bar: v.string(),
})
}
args: {
foo: fooBarValidator()
}

// Works for some reason
export const fooBarValidator = {
foo: v.object({
bar: v.string(),
}),
}
args: {
...fooBarValidator,
}
// Fails in some cases, not sure why
export const fooBarValidator = v.object({
bar: v.string(),
})
args: {
foo: fooBarValidator,
}

// Fails at least some cases, maybe all - different error, "fooBarValidator is not a function" (it certainly is)
export const fooBarValidator = () => {
return v.object({
bar: v.string(),
})
}
args: {
foo: fooBarValidator()
}

// Works for some reason
export const fooBarValidator = {
foo: v.object({
bar: v.string(),
}),
}
args: {
...fooBarValidator,
}
ian
ianā€¢14mo ago
I believe what you're running into is an import cycle. When TypeScript has a cycle, the objects might be undefined while it traverses the imports. Can you try putting the imported validator in a separate file imported in both places? I ran into something like this in AI Town but I don't remember the specifics
erquhart
erquhartOPā€¢14mo ago
Hmm it does sound like an import cycle, true - but it's already in a separate file, the authz file is shared by all of the other files Will try though, that makes sense @ian yep it was an import cycle, thanks for that

Did you find this page helpful?