Environment
"@orpc/server": "^1.8.6",
"@orpc/client": "^1.8.6",
"@orpc/openapi": "^1.8.6",
"@orpc/zod": "^1.8.6",
"@orpc/client": "^1.8.6",
"@orpc/tanstack-query": "^1.8.6",
Reproduction
running api calls with contract inputs (input schemas different than z.void())
every call fails
Describe the bug
when run api calls with the input is not z.void() it fails
with input validation error expecting object revieving undefined everytime
Additional context
import { OpenAPIHandler } from "@orpc/openapi/node";
import { OpenAPIReferencePlugin } from "@orpc/openapi/plugins";
import { onError } from "@orpc/server";
import { RPCHandler } from "@orpc/server/node";
import { ZodToJsonSchemaConverter } from "@orpc/zod/zod4";
import { mobileAuth, webAuth } from "@theguestbook/auth";
import { importEnv, ServerEnvSchema } from "@theguestbook/env/server";
import { toNodeHandler } from "better-auth/node";
import cors from "cors";
import express, { type Request } from "express";
import { createMobileContext } from "./mobile/context";
import { mobileRouter } from "./mobile/routers";
import { createWebContext } from "./web/context";
import { webRouter } from "./web/routers";
// only import root .env in development
if (process.env.npm_lifecycle_script === "tsx watch src/index.ts") {
importEnv();
}
const PORT = 3000;
const SUCCESS_STATUS = 200; // for health check
// for validation on startup
ServerEnvSchema.parse(process.env);
const app = express();
app.use(
cors({
origin: true,
methods: ["GET", "POST", "PUT", "DELETE", "OPTIONS"],
credentials: true,
})
);
app.all("/webApi/auth/{*path}", toNodeHandler(webAuth));
app.all("/mobileApi/auth/{*path}", toNodeHandler(mobileAuth));
app.use(express.json());
app.get("/", (_req, res) => {
res.status(SUCCESS_STATUS).send("OK");
});
const webRpcHandler = new RPCHandler(webRouter, {
interceptors: [
onError((error) => {
// biome-ignore lint/suspicious/noConsole: error logs
console.dir(error);
}),
],
});
const mobileRpcHandler = new RPCHandler(mobileRouter, {
interceptors: [
onError((error) => {
// biome-ignore lint/suspicious/noConsole: error logs
console.dir(error);
}),
],
});
const webApiHandler = new OpenAPIHandler(webRouter, {
plugins: [
new OpenAPIReferencePlugin({
schemaConverters: [new ZodToJsonSchemaConverter()],
}),
],
interceptors: [
onError((error) => {
// biome-ignore lint/suspicious/noConsole: error logs
console.dir(error, { depth: Number.POSITIVE_INFINITY });
}),
],
});
const mobileApiHandler = new OpenAPIHandler(mobileRouter, {
plugins: [
new OpenAPIReferencePlugin({
schemaConverters: [new ZodToJsonSchemaConverter()],
}),
],
interceptors: [
onError((error) => {
// biome-ignore lint/suspicious/noConsole: error logs
console.dir(error);
}),
],
});
app.use(async (req: Request, res, next) => {
const rpcResult = await webRpcHandler.handle(req, res, {
prefix: "/webRpc",
context: await createWebContext(req),
});
if (rpcResult.matched) {
return;
}
const apiResult = await webApiHandler.handle(req, res, {
prefix: "/webApi",
context: await createWebContext(req),
});
if (apiResult.matched) {
return;
}
next();
});
app.use(async (req: Request, res, next) => {
const rpcResult = await mobileRpcHandler.handle(req, res, {
prefix: "/mobileRpc",
context: await createMobileContext(req),
});
if (rpcResult.matched) {
return;
}
const apiResult = await mobileApiHandler.handle(req, res, {
prefix: "/mobileApi",
context: await createMobileContext(req),
});
if (apiResult.matched) {
return;
}
next();
});
const port = process.env.PORT || PORT;
app.listen(port, () => {
// biome-ignore lint/suspicious/noConsole: simple log
console.log(Server is running on port ${port});
});
Logs
{
"defined": false,
"code": "BAD_REQUEST",
"status": 400,
"message": "Input validation failed",
"data": {
"issues": [
{
"expected": "object",
"code": "invalid_type",
"path": [],
"message": "Invalid input: expected object, received undefined"
}
]
}
}
Environment
"@orpc/server": "^1.8.6",
"@orpc/client": "^1.8.6",
"@orpc/openapi": "^1.8.6",
"@orpc/zod": "^1.8.6",
"@orpc/client": "^1.8.6",
"@orpc/tanstack-query": "^1.8.6",
Reproduction
running api calls with contract inputs (input schemas different than z.void())
every call fails
Describe the bug
when run api calls with the input is not z.void() it fails
with input validation error expecting object revieving undefined everytime
Additional context
import { OpenAPIHandler } from "@orpc/openapi/node";
import { OpenAPIReferencePlugin } from "@orpc/openapi/plugins";
import { onError } from "@orpc/server";
import { RPCHandler } from "@orpc/server/node";
import { ZodToJsonSchemaConverter } from "@orpc/zod/zod4";
import { mobileAuth, webAuth } from "@theguestbook/auth";
import { importEnv, ServerEnvSchema } from "@theguestbook/env/server";
import { toNodeHandler } from "better-auth/node";
import cors from "cors";
import express, { type Request } from "express";
import { createMobileContext } from "./mobile/context";
import { mobileRouter } from "./mobile/routers";
import { createWebContext } from "./web/context";
import { webRouter } from "./web/routers";
// only import root .env in development
if (process.env.npm_lifecycle_script === "tsx watch src/index.ts") {
importEnv();
}
const PORT = 3000;
const SUCCESS_STATUS = 200; // for health check
// for validation on startup
ServerEnvSchema.parse(process.env);
const app = express();
app.use(
cors({
origin: true,
methods: ["GET", "POST", "PUT", "DELETE", "OPTIONS"],
credentials: true,
})
);
app.all("/webApi/auth/{*path}", toNodeHandler(webAuth));
app.all("/mobileApi/auth/{*path}", toNodeHandler(mobileAuth));
app.use(express.json());
app.get("/", (_req, res) => {
res.status(SUCCESS_STATUS).send("OK");
});
const webRpcHandler = new RPCHandler(webRouter, {
interceptors: [
onError((error) => {
// biome-ignore lint/suspicious/noConsole: error logs
console.dir(error);
}),
],
});
const mobileRpcHandler = new RPCHandler(mobileRouter, {
interceptors: [
onError((error) => {
// biome-ignore lint/suspicious/noConsole: error logs
console.dir(error);
}),
],
});
const webApiHandler = new OpenAPIHandler(webRouter, {
plugins: [
new OpenAPIReferencePlugin({
schemaConverters: [new ZodToJsonSchemaConverter()],
}),
],
interceptors: [
onError((error) => {
// biome-ignore lint/suspicious/noConsole: error logs
console.dir(error, { depth: Number.POSITIVE_INFINITY });
}),
],
});
const mobileApiHandler = new OpenAPIHandler(mobileRouter, {
plugins: [
new OpenAPIReferencePlugin({
schemaConverters: [new ZodToJsonSchemaConverter()],
}),
],
interceptors: [
onError((error) => {
// biome-ignore lint/suspicious/noConsole: error logs
console.dir(error);
}),
],
});
app.use(async (req: Request, res, next) => {
const rpcResult = await webRpcHandler.handle(req, res, {
prefix: "/webRpc",
context: await createWebContext(req),
});
if (rpcResult.matched) {
return;
}
const apiResult = await webApiHandler.handle(req, res, {
prefix: "/webApi",
context: await createWebContext(req),
});
if (apiResult.matched) {
return;
}
next();
});
app.use(async (req: Request, res, next) => {
const rpcResult = await mobileRpcHandler.handle(req, res, {
prefix: "/mobileRpc",
context: await createMobileContext(req),
});
if (rpcResult.matched) {
return;
}
const apiResult = await mobileApiHandler.handle(req, res, {
prefix: "/mobileApi",
context: await createMobileContext(req),
});
if (apiResult.matched) {
return;
}
next();
});
const port = process.env.PORT || PORT;
app.listen(port, () => {
// biome-ignore lint/suspicious/noConsole: simple log
console.log(
Server is running on port ${port});});
Logs
{ "defined": false, "code": "BAD_REQUEST", "status": 400, "message": "Input validation failed", "data": { "issues": [ { "expected": "object", "code": "invalid_type", "path": [], "message": "Invalid input: expected object, received undefined" } ] } }