Keystone 6自定义Schema Mutation失效:栈溢出错误如何解决?
Keystone 6自定义Mutation栈溢出(Maximum call stack size exceeded)问题排查与解决
核心成因
最常见的触发原因是自定义Mutation解析器中出现无限递归调用:
- 自定义Mutation名称与Keystone自动生成的内置Mutation(比如
update<UserListName>)重名,且在解析器内调用了context.db的更新方法,导致触发自定义Resolver本身,形成循环调用。 - 直接定义
type Mutation而非用extend扩展,完全替换了Keystone自动生成的Mutation类型,引发解析器覆盖冲突,导致递归。
解决步骤
1. 自定义Mutation使用独立命名
Keystone会为每个列表自动生成create<ListName>、update<ListName>等Mutation,自定义逻辑必须用不同名称,比如:
// custom-schema.ts 中的Schema扩展 extend type Mutation { # 避免用 updateUser,改用自定义标识 updateUserWithCustomLogic(id: ID!, data: UserUpdateInput!): User }
2. 直接调用Prisma Client而非context.db
context.db是Keystone封装的上层API,调用时会触发权限校验、钩子及Resolver流程,容易意外调用到自定义Mutation。改用context.prisma直接操作数据库:
// custom-schema.ts 中的解析器实现 export const resolvers = { Mutation: { updateUserWithCustomLogic: async (_, { id, data }, context) => { // 绕开Keystone上层封装,直接用Prisma操作 return context.prisma.user.update({ where: { id }, data, }); }, }, };
3. 确保Schema正确增量扩展
必须使用extend type Mutation来扩展内置Schema,不能直接定义type Mutation——后者会完全替换Keystone自动生成的Mutation类型,引发解析器冲突。
4. 排查权限配置的循环触发
如果自定义Mutation中调用的方法依赖权限校验,且权限规则里又触发了该自定义Mutation,也会导致递归。检查access配置,确保权限逻辑无循环调用。
关键遗漏细节
- 不要混淆
context.db和context.prisma:前者是Keystone的上层封装,会触发完整Resolver流程;后者是底层Prisma Client,直接操作数据库,不会触发自定义Resolver。 - 自定义Schema只能做增量扩展,不能替换原有类型,否则会破坏Keystone的自动生成逻辑。
内容的提问来源于stack exchange,提问作者Tony Barnes
相关产品推荐
相关产品推荐

