From d7886fb7c9705e217f47ec3198941fa8f33172f1 Mon Sep 17 00:00:00 2001 From: Vibe Code Date: Wed, 25 Feb 2026 00:20:25 +0100 Subject: [PATCH 1/4] fix: resolve OpenAPI 500 error caused by BigInt serialization in stopGracePeriodSwarm MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change Drizzle column mode from "bigint" to "number" for stopGracePeriodSwarm across all 6 service schemas. This fixes JSON.stringify failing silently in the @dokploy/trpc-openapi adapter, which unlike the tRPC endpoint does not use superjson and cannot serialize BigInt values. No database migration needed — only the JS representation changes. The values are nanosecond grace periods that fit safely within Number.MAX_SAFE_INTEGER. Also adds onError logging and export const config to the OpenAPI route handler to match the tRPC route and improve debuggability. Fixes #3793 --- .../server/mechanizeDockerContainer.test.ts | 6 +++--- .../advanced/cluster/modify-swarm-settings.tsx | 2 +- .../swarm-forms/stop-grace-period-form.tsx | 10 ++++------ apps/dokploy/pages/api/[...trpc].ts | 15 +++++++++++++++ packages/server/src/db/schema/application.ts | 4 ++-- packages/server/src/db/schema/mariadb.ts | 4 ++-- packages/server/src/db/schema/mongo.ts | 4 ++-- packages/server/src/db/schema/mysql.ts | 4 ++-- packages/server/src/db/schema/postgres.ts | 4 ++-- packages/server/src/db/schema/redis.ts | 4 ++-- packages/server/src/utils/docker/utils.ts | 11 +++-------- 11 files changed, 38 insertions(+), 30 deletions(-) diff --git a/apps/dokploy/__test__/server/mechanizeDockerContainer.test.ts b/apps/dokploy/__test__/server/mechanizeDockerContainer.test.ts index fb448e3af..daf2dbe54 100644 --- a/apps/dokploy/__test__/server/mechanizeDockerContainer.test.ts +++ b/apps/dokploy/__test__/server/mechanizeDockerContainer.test.ts @@ -57,7 +57,7 @@ const createApplication = ( env: null, }, replicas: 1, - stopGracePeriodSwarm: 0n, + stopGracePeriodSwarm: 0, ulimitsSwarm: null, serverId: "server-id", ...overrides, @@ -76,8 +76,8 @@ describe("mechanizeDockerContainer", () => { }); }); - it("converts bigint stopGracePeriodSwarm to a number and keeps zero values", async () => { - const application = createApplication({ stopGracePeriodSwarm: 0n }); + it("passes stopGracePeriodSwarm as a number and keeps zero values", async () => { + const application = createApplication({ stopGracePeriodSwarm: 0 }); await mechanizeDockerContainer(application); diff --git a/apps/dokploy/components/dashboard/application/advanced/cluster/modify-swarm-settings.tsx b/apps/dokploy/components/dashboard/application/advanced/cluster/modify-swarm-settings.tsx index 4c6fc60c7..dc8038793 100644 --- a/apps/dokploy/components/dashboard/application/advanced/cluster/modify-swarm-settings.tsx +++ b/apps/dokploy/components/dashboard/application/advanced/cluster/modify-swarm-settings.tsx @@ -112,7 +112,7 @@ const menuItems: MenuItem[] = [ const hasStopGracePeriodSwarm = ( value: unknown, -): value is { stopGracePeriodSwarm: bigint | number | string | null } => +): value is { stopGracePeriodSwarm: number | string | null } => typeof value === "object" && value !== null && "stopGracePeriodSwarm" in value; diff --git a/apps/dokploy/components/dashboard/application/advanced/cluster/swarm-forms/stop-grace-period-form.tsx b/apps/dokploy/components/dashboard/application/advanced/cluster/swarm-forms/stop-grace-period-form.tsx index a324da31b..53e0d5a3a 100644 --- a/apps/dokploy/components/dashboard/application/advanced/cluster/swarm-forms/stop-grace-period-form.tsx +++ b/apps/dokploy/components/dashboard/application/advanced/cluster/swarm-forms/stop-grace-period-form.tsx @@ -16,7 +16,7 @@ import { api } from "@/utils/api"; const hasStopGracePeriodSwarm = ( value: unknown, -): value is { stopGracePeriodSwarm: bigint | number | string | null } => +): value is { stopGracePeriodSwarm: number | string | null } => typeof value === "object" && value !== null && "stopGracePeriodSwarm" in value; @@ -59,7 +59,7 @@ export const StopGracePeriodForm = ({ id, type }: StopGracePeriodFormProps) => { const form = useForm({ defaultValues: { - value: null as bigint | null, + value: null as number | null, }, }); @@ -69,9 +69,7 @@ export const StopGracePeriodForm = ({ id, type }: StopGracePeriodFormProps) => { const normalizedValue = value === null || value === undefined ? null - : typeof value === "bigint" - ? value - : BigInt(value); + : Number(value); form.reset({ value: normalizedValue, }); @@ -126,7 +124,7 @@ export const StopGracePeriodForm = ({ id, type }: StopGracePeriodFormProps) => { } onChange={(e) => field.onChange( - e.target.value ? BigInt(e.target.value) : null, + e.target.value ? Number(e.target.value) : null, ) } /> diff --git a/apps/dokploy/pages/api/[...trpc].ts b/apps/dokploy/pages/api/[...trpc].ts index 8ee0e9102..b77cb0390 100644 --- a/apps/dokploy/pages/api/[...trpc].ts +++ b/apps/dokploy/pages/api/[...trpc].ts @@ -16,7 +16,22 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => { return createOpenApiNextHandler({ router: appRouter, createContext: createTRPCContext, + onError: + process.env.NODE_ENV === "development" + ? ({ path, error }: { path: string | undefined; error: Error }) => { + console.error( + `❌ OpenAPI failed on ${path ?? ""}: ${error.message}`, + ); + } + : undefined, })(req, res); }; export default handler; + +export const config = { + api: { + bodyParser: false, + sizeLimit: "1gb", + }, +}; diff --git a/packages/server/src/db/schema/application.ts b/packages/server/src/db/schema/application.ts index fc881449d..f8ef8711b 100644 --- a/packages/server/src/db/schema/application.ts +++ b/packages/server/src/db/schema/application.ts @@ -173,7 +173,7 @@ export const applications = pgTable("application", { modeSwarm: json("modeSwarm").$type(), labelsSwarm: json("labelsSwarm").$type(), networkSwarm: json("networkSwarm").$type(), - stopGracePeriodSwarm: bigint("stopGracePeriodSwarm", { mode: "bigint" }), + stopGracePeriodSwarm: bigint("stopGracePeriodSwarm", { mode: "number" }), endpointSpecSwarm: json("endpointSpecSwarm").$type(), ulimitsSwarm: json("ulimitsSwarm").$type(), // @@ -367,7 +367,7 @@ const createSchema = createInsertSchema(applications, { watchPaths: z.array(z.string()).optional(), previewLabels: z.array(z.string()).optional(), cleanCache: z.boolean().optional(), - stopGracePeriodSwarm: z.bigint().nullable(), + stopGracePeriodSwarm: z.number().nullable(), endpointSpecSwarm: EndpointSpecSwarmSchema.nullable(), ulimitsSwarm: UlimitsSwarmSchema.nullable(), }); diff --git a/packages/server/src/db/schema/mariadb.ts b/packages/server/src/db/schema/mariadb.ts index a2dbaa989..932f318fa 100644 --- a/packages/server/src/db/schema/mariadb.ts +++ b/packages/server/src/db/schema/mariadb.ts @@ -67,7 +67,7 @@ export const mariadb = pgTable("mariadb", { modeSwarm: json("modeSwarm").$type(), labelsSwarm: json("labelsSwarm").$type(), networkSwarm: json("networkSwarm").$type(), - stopGracePeriodSwarm: bigint("stopGracePeriodSwarm", { mode: "bigint" }), + stopGracePeriodSwarm: bigint("stopGracePeriodSwarm", { mode: "number" }), endpointSpecSwarm: json("endpointSpecSwarm").$type(), ulimitsSwarm: json("ulimitsSwarm").$type(), replicas: integer("replicas").default(1).notNull(), @@ -142,7 +142,7 @@ const createSchema = createInsertSchema(mariadb, { modeSwarm: ServiceModeSwarmSchema.nullable(), labelsSwarm: LabelsSwarmSchema.nullable(), networkSwarm: NetworkSwarmSchema.nullable(), - stopGracePeriodSwarm: z.bigint().nullable(), + stopGracePeriodSwarm: z.number().nullable(), endpointSpecSwarm: EndpointSpecSwarmSchema.nullable(), ulimitsSwarm: UlimitsSwarmSchema.nullable(), }); diff --git a/packages/server/src/db/schema/mongo.ts b/packages/server/src/db/schema/mongo.ts index 5349823da..31b0824bc 100644 --- a/packages/server/src/db/schema/mongo.ts +++ b/packages/server/src/db/schema/mongo.ts @@ -70,7 +70,7 @@ export const mongo = pgTable("mongo", { modeSwarm: json("modeSwarm").$type(), labelsSwarm: json("labelsSwarm").$type(), networkSwarm: json("networkSwarm").$type(), - stopGracePeriodSwarm: bigint("stopGracePeriodSwarm", { mode: "bigint" }), + stopGracePeriodSwarm: bigint("stopGracePeriodSwarm", { mode: "number" }), endpointSpecSwarm: json("endpointSpecSwarm").$type(), ulimitsSwarm: json("ulimitsSwarm").$type(), replicas: integer("replicas").default(1).notNull(), @@ -139,7 +139,7 @@ const createSchema = createInsertSchema(mongo, { modeSwarm: ServiceModeSwarmSchema.nullable(), labelsSwarm: LabelsSwarmSchema.nullable(), networkSwarm: NetworkSwarmSchema.nullable(), - stopGracePeriodSwarm: z.bigint().nullable(), + stopGracePeriodSwarm: z.number().nullable(), endpointSpecSwarm: EndpointSpecSwarmSchema.nullable(), ulimitsSwarm: UlimitsSwarmSchema.nullable(), }); diff --git a/packages/server/src/db/schema/mysql.ts b/packages/server/src/db/schema/mysql.ts index 3f6e424b7..2b1c60b41 100644 --- a/packages/server/src/db/schema/mysql.ts +++ b/packages/server/src/db/schema/mysql.ts @@ -65,7 +65,7 @@ export const mysql = pgTable("mysql", { modeSwarm: json("modeSwarm").$type(), labelsSwarm: json("labelsSwarm").$type(), networkSwarm: json("networkSwarm").$type(), - stopGracePeriodSwarm: bigint("stopGracePeriodSwarm", { mode: "bigint" }), + stopGracePeriodSwarm: bigint("stopGracePeriodSwarm", { mode: "number" }), endpointSpecSwarm: json("endpointSpecSwarm").$type(), ulimitsSwarm: json("ulimitsSwarm").$type(), replicas: integer("replicas").default(1).notNull(), @@ -139,7 +139,7 @@ const createSchema = createInsertSchema(mysql, { modeSwarm: ServiceModeSwarmSchema.nullable(), labelsSwarm: LabelsSwarmSchema.nullable(), networkSwarm: NetworkSwarmSchema.nullable(), - stopGracePeriodSwarm: z.bigint().nullable(), + stopGracePeriodSwarm: z.number().nullable(), endpointSpecSwarm: EndpointSpecSwarmSchema.nullable(), ulimitsSwarm: UlimitsSwarmSchema.nullable(), }); diff --git a/packages/server/src/db/schema/postgres.ts b/packages/server/src/db/schema/postgres.ts index cfd969aaa..cd9ea8a3e 100644 --- a/packages/server/src/db/schema/postgres.ts +++ b/packages/server/src/db/schema/postgres.ts @@ -65,7 +65,7 @@ export const postgres = pgTable("postgres", { modeSwarm: json("modeSwarm").$type(), labelsSwarm: json("labelsSwarm").$type(), networkSwarm: json("networkSwarm").$type(), - stopGracePeriodSwarm: bigint("stopGracePeriodSwarm", { mode: "bigint" }), + stopGracePeriodSwarm: bigint("stopGracePeriodSwarm", { mode: "number" }), endpointSpecSwarm: json("endpointSpecSwarm").$type(), ulimitsSwarm: json("ulimitsSwarm").$type(), replicas: integer("replicas").default(1).notNull(), @@ -133,7 +133,7 @@ const createSchema = createInsertSchema(postgres, { modeSwarm: ServiceModeSwarmSchema.nullable(), labelsSwarm: LabelsSwarmSchema.nullable(), networkSwarm: NetworkSwarmSchema.nullable(), - stopGracePeriodSwarm: z.bigint().nullable(), + stopGracePeriodSwarm: z.number().nullable(), endpointSpecSwarm: EndpointSpecSwarmSchema.nullable(), ulimitsSwarm: UlimitsSwarmSchema.nullable(), }); diff --git a/packages/server/src/db/schema/redis.ts b/packages/server/src/db/schema/redis.ts index aa76fdbcb..0df6f98c5 100644 --- a/packages/server/src/db/schema/redis.ts +++ b/packages/server/src/db/schema/redis.ts @@ -64,7 +64,7 @@ export const redis = pgTable("redis", { modeSwarm: json("modeSwarm").$type(), labelsSwarm: json("labelsSwarm").$type(), networkSwarm: json("networkSwarm").$type(), - stopGracePeriodSwarm: bigint("stopGracePeriodSwarm", { mode: "bigint" }), + stopGracePeriodSwarm: bigint("stopGracePeriodSwarm", { mode: "number" }), endpointSpecSwarm: json("endpointSpecSwarm").$type(), ulimitsSwarm: json("ulimitsSwarm").$type(), replicas: integer("replicas").default(1).notNull(), @@ -121,7 +121,7 @@ const createSchema = createInsertSchema(redis, { modeSwarm: ServiceModeSwarmSchema.nullable(), labelsSwarm: LabelsSwarmSchema.nullable(), networkSwarm: NetworkSwarmSchema.nullable(), - stopGracePeriodSwarm: z.bigint().nullable(), + stopGracePeriodSwarm: z.number().nullable(), endpointSpecSwarm: EndpointSpecSwarmSchema.nullable(), ulimitsSwarm: UlimitsSwarmSchema.nullable(), }); diff --git a/packages/server/src/utils/docker/utils.ts b/packages/server/src/utils/docker/utils.ts index 144df2c14..1274087bb 100644 --- a/packages/server/src/utils/docker/utils.ts +++ b/packages/server/src/utils/docker/utils.ts @@ -511,11 +511,6 @@ export const generateConfigContainer = ( ulimitsSwarm, } = application; - const sanitizedStopGracePeriodSwarm = - typeof stopGracePeriodSwarm === "bigint" - ? Number(stopGracePeriodSwarm) - : stopGracePeriodSwarm; - const haveMounts = mounts && mounts.length > 0; return { @@ -562,9 +557,9 @@ export const generateConfigContainer = ( Order: "start-first", }, }), - ...(sanitizedStopGracePeriodSwarm !== null && - sanitizedStopGracePeriodSwarm !== undefined && { - StopGracePeriod: sanitizedStopGracePeriodSwarm, + ...(stopGracePeriodSwarm !== null && + stopGracePeriodSwarm !== undefined && { + StopGracePeriod: stopGracePeriodSwarm, }), ...(networkSwarm ? { From 6e9c5c79dcd7c838633ff01971e3285664fc19f4 Mon Sep 17 00:00:00 2001 From: "autofix-ci[bot]" <114827586+autofix-ci[bot]@users.noreply.github.com> Date: Sun, 5 Apr 2026 05:06:42 +0000 Subject: [PATCH 2/4] [autofix.ci] apply automated fixes --- .../advanced/cluster/swarm-forms/stop-grace-period-form.tsx | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/apps/dokploy/components/dashboard/application/advanced/cluster/swarm-forms/stop-grace-period-form.tsx b/apps/dokploy/components/dashboard/application/advanced/cluster/swarm-forms/stop-grace-period-form.tsx index c37116380..ebc93a388 100644 --- a/apps/dokploy/components/dashboard/application/advanced/cluster/swarm-forms/stop-grace-period-form.tsx +++ b/apps/dokploy/components/dashboard/application/advanced/cluster/swarm-forms/stop-grace-period-form.tsx @@ -76,9 +76,7 @@ export const StopGracePeriodForm = ({ id, type }: StopGracePeriodFormProps) => { if (hasStopGracePeriodSwarm(data)) { const value = data.stopGracePeriodSwarm; const normalizedValue = - value === null || value === undefined - ? null - : Number(value); + value === null || value === undefined ? null : Number(value); form.reset({ value: normalizedValue, }); From 32758b29a777b455b97066002e1d21da5dfdea9e Mon Sep 17 00:00:00 2001 From: Mauricio Siu Date: Sat, 4 Apr 2026 23:09:55 -0600 Subject: [PATCH 3/4] fix: change stopGracePeriodSwarm type from bigint to number in schema --- packages/server/src/db/schema/libsql.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/server/src/db/schema/libsql.ts b/packages/server/src/db/schema/libsql.ts index 0d5e98b78..046f985f7 100644 --- a/packages/server/src/db/schema/libsql.ts +++ b/packages/server/src/db/schema/libsql.ts @@ -79,7 +79,7 @@ export const libsql = pgTable("libsql", { modeSwarm: json("modeSwarm").$type(), labelsSwarm: json("labelsSwarm").$type(), networkSwarm: json("networkSwarm").$type(), - stopGracePeriodSwarm: bigint("stopGracePeriodSwarm", { mode: "bigint" }), + stopGracePeriodSwarm: bigint("stopGracePeriodSwarm", { mode: "number" }), endpointSpecSwarm: json("endpointSpecSwarm").$type(), replicas: integer("replicas").default(1).notNull(), createdAt: text("createdAt") @@ -143,7 +143,7 @@ const createSchema = createInsertSchema(libsql, { modeSwarm: ServiceModeSwarmSchema.nullable(), labelsSwarm: LabelsSwarmSchema.nullable(), networkSwarm: NetworkSwarmSchema.nullable(), - stopGracePeriodSwarm: z.bigint().nullable(), + stopGracePeriodSwarm: z.number().nullable(), endpointSpecSwarm: EndpointSpecSwarmSchema.nullable(), }); From f076e720465c51cfda311618e509704bc0710238 Mon Sep 17 00:00:00 2001 From: Mauricio Siu Date: Sat, 4 Apr 2026 23:11:14 -0600 Subject: [PATCH 4/4] refactor: remove unused API configuration for bodyParser and sizeLimit --- apps/dokploy/pages/api/[...trpc].ts | 7 ------- 1 file changed, 7 deletions(-) diff --git a/apps/dokploy/pages/api/[...trpc].ts b/apps/dokploy/pages/api/[...trpc].ts index b77cb0390..83ff9b050 100644 --- a/apps/dokploy/pages/api/[...trpc].ts +++ b/apps/dokploy/pages/api/[...trpc].ts @@ -28,10 +28,3 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => { }; export default handler; - -export const config = { - api: { - bodyParser: false, - sizeLimit: "1gb", - }, -};