schema failed to update in dashboard
I am currently working on a NextJs with Convex project, but i am having issues updating the schema of already added documents to my database, who can help to fix this please as i have been trying without being able to. I will really appreciate any help...
i keep getting the following error:
$ npx convex dev
(node:25832) [DEP0040] DeprecationWarning: The
punycode
module is deprecated. Please use a userland alternative instead.
(Use node --trace-deprecation ...
to show where the warning was created)
✔ Schema validation complete.
Downloading current deployment state...
Diffing local code and deployment state
Analyzing and deploying source code...
✖ Error: Unable to push deployment config to https://judicious-gazelle-541.convex.cloud
Error fetching POST https://judicious-gazelle-541.convex.cloud/api/push_config 400 Bad Request: InvalidModules: Hit an error while pushing:
Loading the pushed modules encountered the following
error:
Unable to parse JSON from exportArgs
: Error in args validator: Invalid validator for key audioStorageId
: Not a field validator
See https://docs.convex.dev/functions/validation for docs on how to do argument validation.Argument and Return Value Validation | Convex Developer Hub
Argument and return value validators ensure that
34 Replies
Can you share the
args
for the function that takes in audioStorageId
?sure thanks for your time and the reply
export const createPost = mutation({
args: {
// audioStorageId: v.union(v.id("_storage"), v.null()),
// audioStorageId: v.optional(v.union(v.id("_storage"), v.null())),
audioStorageId: v.any(),
postTitle: v.string(),
postDescription: v.string(),
// audioUrl: v.string(),
imageUrl: v.string(),
imageStorageId: v.union(v.id("_storage"), v.null()),
postContent: v.string(),
imagePrompt: v.string(),
postCategory: v.string(),
views: v.number(),
likes: v.number(),
// audioDuration: v.number(),
},
handler: async (ctx, args) => {
const identity = await ctx.auth.getUserIdentity();
if (!identity) {
throw new ConvexError("User not authenticated");
}
const user = await ctx.db
.query("users")
.filter((q) => q.eq(q.field("email"), identity.email))
.collect();
if (user.length === 0) {
throw new ConvexError("User not found");
}
return await ctx.db.insert("posts", {
audioStorageId: args.audioStorageId,
user: user[0]._id,
postTitle: args.postTitle,
postDescription: args.postDescription,
audioUrl: args.audioUrl,
imageUrl: args.imageUrl,
imageStorageId: args.imageStorageId,
author: user[0].name,
authorId: user[0].clerkId,
postContent: args.postContent,
imagePrompt: args.imagePrompt,
postCategory: args.postCategory,
views: args.views,
likes: args.likes,
authorImageUrl: user[0].imageUrl,
audioDuration: args.audioDuration,
});
},
});
you will notice in the args i have tried different means to update the audioStorageId key but it doesnt update on the dashboard..
and the following is my schema file:
export default defineSchema({
posts: defineTable({
user: v.id("users"),
postTitle: v.string(),
postContent: v.string(),
postCategory: v.string(),
postDescription: v.string(),
audioUrl: v.optional(v.string()),
imageStorageId: v.optional(v.id("_storage")),
// audioStorageId: v.optional(v.union(v.id("_storage"), v.null())),
// audioStorageId: v.optional(v.id("_storage")),
// audioStorageId: v.union(v.id("_storage"), v.null()),
audioStorageId: v.any(),
author: v.string(),
authorId: v.string(),
authorImageUrl: v.string(),
imageUrl: v.string(),
imagePrompt: v.string(),
// audioDuration: v.number(),
views: v.number(),
likes: v.optional(v.number()),
})
.searchIndex("search_author", {searchField: "author"})
.searchIndex("search_title", {searchField: "postTitle"})
.searchIndex("search_body", {searchField: "postDescription"}),
users: defineTable({
email: v.string(),
imageUrl: v.string(),
clerkId: v.string(),
name: v.string(),
}),
// ... your existing tables ...
comments: defineTable({
postId: v.id("posts"),
userId: v.id("users"),
content: v.string(),
createdAt: v.number(),
}).index("by_post", ["postId"]),
});
That looks good to me. Is it possible you have another function that takes in
audioStorageId
as an argument? I might also try restarting npx convex dev
to see if that does anythingi have tried npx convex dev several times, can i try npx convex deploy too or is it a different function
the code was previously working fine, but as soon as i tried to add a new feature whereby i can save already created posts to bookmarks as savedPosts, i have been getting the error since then even after i removed the schema for the new created document of savedPost completely...
i have been thinking its a cache issue but not sure, maybe their is a command to clear the cache
npx convex deploy pushes the code to a different convex deployment (prod), which you can do if you want but probably won't have different results. I'm not sure what the issue could be here
Each time you run npx convex dev you get the error about audioStorageId and exportArgs?
tried changing the validaot for the key to audioStorageId: v.optional(v.string()),
which triggers a new error that:
npx convex dev
(node:20668) [DEP0040] DeprecationWarning: The
punycode
module is deprecated. Please use a userland alternative instead.
(Use node --trace-deprecation ...
to show where the warning was created)
✖ Schema validation failed
Document with ID "jh747tjvj7bs5p1tanj01g55ad6wkzdv" in table "posts" does not match the schema: Value does not match validator.
Path: .audioStorageId
Value: null
Validator: v.id("_storage")
i guess it happened because audioStorageId was already saved as null..Try
v.optional(v.any())
and change it in both the args and the schema?Okay trying that now..
Then if that works you can see if
v.optional(v.union(v.null(), v.id("_storage")))
worksso i tried that and it triggered same initial error, but what i noticed specifically is that, convex dashboard does not change everytime i change the value.. here is an attached image of convex schema on dashboard
i think that is the main issue, which led to code to break completely as it disconnect my codebase from convex
Can you paste the error again? I'm confused because the original error was about the args validator but the args validator looks fine to me
The dashboard will not update until there's a successful push without errors
Filesystem changed during push, retrying...
✔ Schema validation complete.
Downloading current deployment state...
Diffing local code and deployment state
Analyzing and deploying source code...
✖ Error: Unable to push deployment config to https://judicious-gazelle-541.convex.cloud
Error fetching POST https://judicious-gazelle-541.convex.cloud/api/push_config 400 Bad Request: InvalidModules: Hit an error while pushing:
Loading the pushed modules encountered the following
error:
Unable to parse JSON from
exportArgs
: Error in args validator: Invalid validator for key audioStorageId
: Not a field validator
See https://docs.convex.dev/functions/validation for docs on how to do argument validation.Argument and Return Value Validation | Convex Developer Hub
Argument and return value validators ensure that
ohh i see..
Ok next thing i would try is commenting out
args: { ... }
entirely and see if the error changes (we can add it back later)okay, trying that now
✖ Schema validation failed
Document with ID "jh747tjvj7bs5p1tanj01g55ad6wkzdv" in table "posts" does not match the schema: Object contains extra field
audioStorageId
that is not in
the validator.
Object: {audioStorageId: null, author: "RA", authorId: "user_2im6tAuMCHdIPR5e28RGNxejLKA", authorImageUrl: "https://img.clerk.com/eyJ0eXBlIjoicHJveHkiLCJzcmMiOiJodHRwczovL2ltYWdlcy5jbGVyay5kZXYvb2F1dGhfZ29vZ2xlL2ltZ18yaW02dEZXYkRIY2p1ZURCTmIyRUhWbGNlOVMifQ", imagePrompt: "", imageStorageId: "kg25nz5y24pvjaec8bypr65cw96wj1va", imageUrl: "https://judicious-gazelle-541.convex.cloud/api/storage/0c19c4ef-42c4-493d-aba6-ac7471af0cf2", likes: 0.0, postCategory: "Artificial Intelligence", postContent: "THIS IS A TEST POST, THIS IS A TEST POST, THIS IS A TEST POST", postDescription: "THIS IS A TEST POST", postTitle: "first post", user: "jd7e3hpyceka0d29ver6a79n4x6w81pr", views: 0.0}
Validator: v.object({audioUrl: v.optional(v.string()), author: v.string(), authorId: v.string(), authorImageUrl: v.string(), imagePrompt: v.string(), imageStorageId: v.optional(v.id("_storage")), imageUrl: v.string(), likes: v.optional(v.float64()), postCategory: v.string(), postContent: v.string(), postDescription: v.string(), postTitle: v.string(), user: v.id("users"), views: v.float64()})
so i got that new error when i tried v.optional(v.any())What does the schema look like when you get that error?
If schema still has
audioStorageId: v.optional(v.any())
this error is very confusing
I'm trying to narrow down the issue by making everything as permissive as possible, which is optional(any) in the schema and removing args validatorokay so we do this one step at a time, when i added v.optional(v.any()) as you mentioned:
i got the the last error i sent,
here is the schema:
import { defineSchema, defineTable } from "convex/server";
import { v } from "convex/values";
export default defineSchema({
posts: defineTable({
user: v.id("users"),
postTitle: v.string(),
postContent: v.string(),
postCategory: v.string(),
postDescription: v.string(),
audioUrl: v.optional(v.string()),
imageStorageId: v.optional(v.id("_storage")),
// audioStorageId: v.optional(v.union(v.id("_storage"), v.null())),
// audioStorageId: v.union(v.id("_storage"), v.null()),
// audioStorageId: v.any(),
// audioStorageId: v.optional(v.union(v.null(), v.id("_storage"))),
audioStorageId: v.optional(v.any()),
author: v.string(),
authorId: v.string(),
authorImageUrl: v.string(),
imageUrl: v.string(),
imagePrompt: v.string(),
// audioDuration: v.number(),
views: v.number(),
likes: v.optional(v.number()),
})
.searchIndex("search_author", {searchField: "author"})
.searchIndex("search_title", {searchField: "postTitle"})
.searchIndex("search_body", {searchField: "postDescription"}),
users: defineTable({
email: v.string(),
imageUrl: v.string(),
clerkId: v.string(),
name: v.string(),
}),
// ... your existing tables ...
comments: defineTable({
postId: v.id("posts"),
userId: v.id("users"),
content: v.string(),
createdAt: v.number(),
}).index("by_post", ["postId"]),
});
here is the convex function to add function:
export const createPost = mutation({
args: {
// audioStorageId: v.union(v.id("_storage"), v.null()),
// audioStorageId: v.optional(v.union(v.id("_storage"), v.null())),
// audioStorageId: v.optional(v.union(v.null(), v.id("_storage"))),
audioStorageId: v.optional(v.any()),
postTitle: v.string(),
postDescription: v.string(),
// audioUrl: v.string(),
imageUrl: v.string(),
imageStorageId: v.union(v.id("_storage"), v.null()),
postContent: v.string(),
imagePrompt: v.string(),
postCategory: v.string(),
views: v.number(),
likes: v.number(),
// audioDuration: v.number(),
},
handler: async (ctx, args) => {
const identity = await ctx.auth.getUserIdentity();
if (!identity) {
throw new ConvexError("User not authenticated");
}
const user = await ctx.db
.query("users")
.filter((q) => q.eq(q.field("email"), identity.email))
.collect();
if (user.length === 0) {
throw new ConvexError("User not found");
}
return await ctx.db.insert("posts", {
audioStorageId: args.audioStorageId,
user: user[0]._id,
postTitle: args.postTitle,
postDescription: args.postDescription,
audioUrl: args.audioUrl,
imageUrl: args.imageUrl,
imageStorageId: args.imageStorageId,
author: user[0].name,
authorId: user[0].clerkId,
postContent: args.postContent,
imagePrompt: args.imagePrompt,
postCategory: args.postCategory,
views: args.views,
likes: args.likes,
authorImageUrl: user[0].imageUrl,
audioDuration: args.audioDuration,
});
},
});
do you have a github repo
yeah sure
here is my github repo:
https://github.com/Oreolion/ra-ai-powered-blogging-platform
GitHub
GitHub - Oreolion/ra-ai-powered-blogging-platform
Contribute to Oreolion/ra-ai-powered-blogging-platform development by creating an account on GitHub.
is this up to date with the current issue
GitHub
ra-ai-powered-blogging-platform/convex/posts.ts at master · Oreolio...
Contribute to Oreolion/ra-ai-powered-blogging-platform development by creating an account on GitHub.
heh that was my first guess
Is it possible you have another function that takes in audioStorageId as an argument?we should change the error message to include the name of the function
github>
please how do you mean specifically, How do i make that work
you should replace
audioStorageId: v.id("_storage") | null,
with audioStorageId: v.optional(v.union(v.id("_storage"), v.null())),
.
we (convex) should change the error message to make it more obviousno he means convex team should
lee out here solving all the problems
Oh okay i will do that.
do i change it only in schema or also in my mutation function
it looks right everwhere else but i could be missing something
crazy!! i cant believe i have been checking a different function all this while... Thanks..
It will surely be helpful to make the error more obvious..
felt that
this led to some experimentation with what the
v.id("_storage") | null
is doing. turns out it evaluates to zero. and another fun one: { foo: true | null }
-> { foo: 1 }