Nick
Nick5mo ago

No "mutation"-procedure on path

Hello all, I am using the latest version of TRPC on my client and server. I am using React Query on my client and AWS Lambda on my server side. When trying to perform a test mutation:
export default function () {
const organizationCreate = trpc.insert_superUser.useMutation();
const insertTestOrg = async () => {
const repsonse = organizationCreate.mutate({
name: "Test Organization",
description: "Test Description",
}, {
onError: (error) => {
console.log("Error", error);
}
})
}
return (<div>
<Button variant="primary" onClick={() => insertTestOrg()}>Button</Button>
</div>)
}
export default function () {
const organizationCreate = trpc.insert_superUser.useMutation();
const insertTestOrg = async () => {
const repsonse = organizationCreate.mutate({
name: "Test Organization",
description: "Test Description",
}, {
onError: (error) => {
console.log("Error", error);
}
})
}
return (<div>
<Button variant="primary" onClick={() => insertTestOrg()}>Button</Button>
</div>)
}
I get the following error Error TRPCClientError: No "mutation"-procedure on path "insert_superUser" I am using a Meta to make sure only users of a specified role can call certain functions, like so:
interface Meta {
role: Role;
}
const t = initTRPC.context<Context>().meta<Meta>().create({
defaultMeta: {
role: Role.OrganizationUser
}
});

export const authRoleProcedure = t.procedure.use(async (opts) => {
const { meta, next, ctx } = opts;
if (!meta?.role) {
throw new TRPCError({ code: 'INTERNAL_SERVER_ERROR', message: 'Role not defined in meta' });
}
if (!ctx.user) {
throw new TRPCError({ code: 'BAD_REQUEST', message: 'User not defined in context'});
}
if (ctx.user.role > meta.role) {
throw new TRPCError({ code: 'UNAUTHORIZED', message: `User does not have the required role. Required: ${meta.role}, User: ${ctx.user.role}`});
}
console.log('User has the required role')
return next();
});

export const router = t.router;
interface Meta {
role: Role;
}
const t = initTRPC.context<Context>().meta<Meta>().create({
defaultMeta: {
role: Role.OrganizationUser
}
});

export const authRoleProcedure = t.procedure.use(async (opts) => {
const { meta, next, ctx } = opts;
if (!meta?.role) {
throw new TRPCError({ code: 'INTERNAL_SERVER_ERROR', message: 'Role not defined in meta' });
}
if (!ctx.user) {
throw new TRPCError({ code: 'BAD_REQUEST', message: 'User not defined in context'});
}
if (ctx.user.role > meta.role) {
throw new TRPCError({ code: 'UNAUTHORIZED', message: `User does not have the required role. Required: ${meta.role}, User: ${ctx.user.role}`});
}
console.log('User has the required role')
return next();
});

export const router = t.router;
1 Reply
Nick
Nick5mo ago
This is how I am using the mutation on the server-side:
export const OrganizationRouter = router({
insert_superUser: authRoleProcedure.meta({ role: Role.SuperUser })
.input(NewOrganization)
.output(z.object({
success: z.boolean(),
message: z.string().optional(),
}))
.mutation(async ({ input }) => {
const response = await db.insert(Organization).values(input).returning();
if (response[0].id) {
return {
success: true,
};
}
return {
success: false,
message: "Organization not inserted",
};
}),
})
export const OrganizationRouter = router({
insert_superUser: authRoleProcedure.meta({ role: Role.SuperUser })
.input(NewOrganization)
.output(z.object({
success: z.boolean(),
message: z.string().optional(),
}))
.mutation(async ({ input }) => {
const response = await db.insert(Organization).values(input).returning();
if (response[0].id) {
return {
success: true,
};
}
return {
success: false,
message: "Organization not inserted",
};
}),
})
My app router is like this:
const myAppRouter = router({
organizationRouter: OrganizationRouter
});

export type AppRouter = typeof OrganizationRouter;

export const handler = awsLambdaRequestHandler({
router: myAppRouter,
createContext,
});
const myAppRouter = router({
organizationRouter: OrganizationRouter
});

export type AppRouter = typeof OrganizationRouter;

export const handler = awsLambdaRequestHandler({
router: myAppRouter,
createContext,
});