I've been playing around with Prisma and I came across a pretty cryptic error message based on what turned out to be a problem in my resolver.
See error message
Error: Variable "$_v0_data" got invalid value {"name":"New Recipe","ingredients":[{"name":"Ingredient 1","quantity":"1"},{"name":"Ingredient 2","quantity":"2"}],"instructions":["Step 1","Step 2"],"categories":[{"name":"SNACK"},{"name":"DINNER"}]}; Field "0" is not defined by type RecipeCreateinstructionsInput at value.instructions.
Variable "$_v0_data" got invalid value {"name":"New Recipe","ingredients":[{"name":"Ingredient 1","quantity":"1"},{"name":"Ingredient 2","quantity":"2"}],"instructions":["Step 1","Step 2"],"categories":[{"name":"SNACK"},{"name":"DINNER"}]}; Field "1" is not defined by type RecipeCreateinstructionsInput at value.instructions.
Variable "$_v0_data" got invalid value {"name":"New Recipe","ingredients":[{"name":"Ingredient 1","quantity":"1"},{"name":"Ingredient 2","quantity":"2"}],"instructions":["Step 1","Step 2"],"categories":[{"name":"SNACK"},{"name":"DINNER"}]}; Field "0" is not defined by type IngredientCreateManyInput at value.ingredients.
Variable "$_v0_data" got invalid value {"name":"New Recipe","ingredients":[{"name":"Ingredient 1","quantity":"1"},{"name":"Ingredient 2","quantity":"2"}],"instructions":["Step 1","Step 2"],"categories":[{"name":"SNACK"},{"name":"DINNER"}]}; Field "1" is not defined by type IngredientCreateManyInput at value.ingredients.
Variable "$_v0_data" got invalid value {"name":"New Recipe","ingredients":[{"name":"Ingredient 1","quantity":"1"},{"name":"Ingredient 2","quantity":"2"}],"instructions":["Step 1","Step 2"],"categories":[{"name":"SNACK"},{"name":"DINNER"}]}; Field "0" is not defined by type CategoryCreateManyWithoutRecipesInput at value.categories.
Variable "$_v0_data" got invalid value {"name":"New Recipe","ingredients":[{"name":"Ingredient 1","quantity":"1"},{"name":"Ingredient 2","quantity":"2"}],"instructions":["Step 1","Step 2"],"categories":[{"name":"SNACK"},{"name":"DINNER"}]}; Field "1" is not defined by type CategoryCreateManyWithoutRecipesInput at value.categories.
at new CombinedError (/Users/Darryl/Projects/server/node_modules/graphql-tools/dist/stitching/errors.js:83:28)
at Object.checkResultAndHandleErrors (/Users/Darryl/Projects/server/node_modules/graphql-tools/dist/stitching/errors.js:101:15)
at CheckResultAndHandleErrors.transformResult (/Users/Darryl/Projects/server/node_modules/graphql-tools/dist/transforms/CheckResultAndHandleErrors.js:10:25)
at /Users/Darryl/Projects/server/node_modules/graphql-tools/dist/transforms/transforms.js:19:54
at Array.reduce (<anonymous>)
at applyResultTransforms (/Users/Darryl/Projects/server/node_modules/graphql-tools/dist/transforms/transforms.js:18:23)
at /Users/Darryl/Projects/server/node_modules/graphql-tools/dist/stitching/delegateToSchema.js:82:50
at step (/Users/Darryl/Projects/server/node_modules/graphql-tools/dist/stitching/delegateToSchema.js:32:23)
at Object.next (/Users/Darryl/Projects/server/node_modules/graphql-tools/dist/stitching/delegateToSchema.js:13:53)
at fulfilled (/Users/Darryl/Projects/server/node_modules/graphql-tools/dist/stitching/delegateToSchema.js:4:58)
createRecipe: (_, args, context, info) => {
return context.prisma.mutation.createRecipe(
{
data: {
name: args.name,
ingredients: args.ingredients,
instructions: args.instructions,
categories: args.categories
}
},
info
);
}
enum Categories {
BREAKFAST
LUNCH
DINNER
SNACK
}
input IngredientInput {
name: String!
quantity: String!
}
input CategoryInput {
name: Categories
}
type Mutation {
createRecipe(
name: String!
ingredients: [IngredientInput!]!
instructions: [String!]!
categories: [CategoryInput!]!
): Recipe
}
Apologies if this isn't the correct format or location for this but I was pointed here by one of the Prisma developers who was helping me debug this.
The solution ended up being this:
createRecipe: (_, args, context, info) => {
return context.prisma.mutation.createRecipe(
{
data: {
name: args.name,
instructions: {
set: args.instructions
},
ingredients: {
create: [...args.ingredients]
},
categories: {
connect: [...args.categories]
}
}
},
info
);
}
Thank you so much, this is exactly what i needed
@WrightManufacturing I'm glad it helped. I was stuck on this for longer than I'd like to admit. 😉
@darrylyoung Thank you. you've saved me several hours.
Thank you! I actually _did_ waste several hours trying to figure this out before finding your comment. does anyone know why if I pass an ID multiple times into a create mutation like this the object that's returned only has one instance of the connected type? for example....
# datamodel.prisma
type Technique {
id: ID! @unique
name: String! @unique
description: String
}
type Combination {
id: ID! @unique
name: String
numTechniques: Int @default(value: "1")
techniques: [Technique!]!
}
# schema.graphql
input TechniqueInput {
id: ID!
}
type Mutation {
createCombination(
name: String
numTechniques: Int
techniques: [TechniqueInput!]!
): Combination
}
md5-a3f313f6259ce8382506e69134fd86ee
// Mutation.js
module.exports = {
createCombination: async (parent, args, ctx, info) => {
return await ctx.db.mutation.createCombination({
data: {
name: args.name,
numTechniques: args.numTechniques,
techniques: {
connect: [...args.techniques]
}
}
}, info)
}
}
md5-c0b7001371af28cfa486e77edcf562ae
mutation {
createCombination (
name: "test 4"
numTechniques: 2
techniques: [
{
id: "cjqgo45x8000s0901z15z86ql"
},
{
id: "cjqgo45x8000s0901z15z86ql"
}
]
)
{
name
techniques {
name
}
}
}
md5-71380bce1cb449cc6e33c64690342986
{
"data": {
"createCombination": {
"name": "test combination",
"techniques": [
{
"name": "technique 1"
}
]
}
}
}
For anyone else who is still struggling with this, because eventually searching the various bits of the Field "0" is not defined by type message will lead here, I wanted to share my fix since I had a slightly different issue. Thanks though @darrylyoung for helping me get my syntax figued out.
Here what I had in my resolver that was causing the error:
const post = await ctx.db.mutation.createPost(
{
data: {
images: {
connect: [...args.images]
},
user: {
connect: {
id: userid
}
},
...args // this was the problem
}
},
info
);
what I needed was:
const post = await ctx.db.mutation.createPost(
{
data: {
images: {
connect: [...args.images]
},
user: {
connect: {
id: userid
}
},
title: args.title,
postContent: args.postContent
}
},
info
);
I think ...args was taking over the "images" field, and even though the connect: [...args.images] was correct prisma would try with the array of ID objects that I passed to set that connection up.
Hope this helps someone :)
Closing, above sounds like a prisma issue rather than a graphql-tools issue. Also seems solved. :)