Problem
When using better-convex ORM inside t.run() (from convex-test), returning objects that contain timestamp() fields causes a serialization crash. The ORM correctly hydrates these fields as JS Date objects, but convex-test serializes t.run() return values through Convex's convexToJson, which does not support native Date objects.
Error
Error: Date "2026-02-24T17:23:11.922Z" is not a supported Convex type
(present at path .createdAt in original object {...}).
Reproduction
import { convexTest } from "../setup.testing";
import { withOrm } from "../lib/orm";
import schema, { organizationTable } from "./schema";
it("returns a Date object from t.run without crashing", async () => {
const t = convexTest(schema);
// This crashes ❌
const result = await t.run(async (baseCtx) => {
const ctx = withOrm(baseCtx);
const [org] = await ctx.orm
.insert(organizationTable)
.values({ name: "Test", slug: "test", monthlyCredits: 100, ... })
.returning();
return org; // org.createdAt is a Date — convex-test can't serialize it
});
});
Current workaround
We have to manually extract primitives or convert dates to strings inside every t.run:
const result = await t.run(async (baseCtx) => {
const ctx = withOrm(baseCtx);
const run = await ctx.orm.query.analysisRun.findFirst({ where: { id } });
return {
status: run?.status ?? null,
completedAt: run?.completedAt?.toISOString() ?? null, // manual conversion
};
});
This is tedious and error-prone — every test that reads ORM data inside t.run needs this boilerplate.
Expected behavior
Returning ORM-hydrated objects (with Date fields from timestamp() columns) from t.run() should work seamlessly. The ORM could dehydrate Date objects back to Convex-compatible values (e.g., number timestamps) before t.run serializes the return value.
Possible solutions
- Dehydrate in the ORM layer: Add a
dehydrateDateFields() counterpart to hydrateDateFieldsForRead() that converts Date → number (ms timestamp), and apply it automatically when the return value crosses the t.run boundary.
- Provide a helper: Export a
toConvexValue(obj) utility that users can wrap their return values with.
- Patch
t.run in convex-test setup: Override the serialization to handle Date → number conversion (this might belong in convex-test itself rather than better-convex).
Environment
better-convex@0.6.0
convex-test@0.0.41
convex@1.32.0
Related
This is a follow-up to #93 which fixed .returning() with nullable timestamps and findFirst returning null. That PR fixed the production ORM behavior, but this serialization issue remains specifically in the convex-test testing context.
Problem
When using better-convex ORM inside
t.run()(fromconvex-test), returning objects that containtimestamp()fields causes a serialization crash. The ORM correctly hydrates these fields as JSDateobjects, butconvex-testserializest.run()return values through Convex'sconvexToJson, which does not support nativeDateobjects.Error
Reproduction
Current workaround
We have to manually extract primitives or convert dates to strings inside every
t.run:This is tedious and error-prone — every test that reads ORM data inside
t.runneeds this boilerplate.Expected behavior
Returning ORM-hydrated objects (with
Datefields fromtimestamp()columns) fromt.run()should work seamlessly. The ORM could dehydrateDateobjects back to Convex-compatible values (e.g.,numbertimestamps) beforet.runserializes the return value.Possible solutions
dehydrateDateFields()counterpart tohydrateDateFieldsForRead()that convertsDate→number(ms timestamp), and apply it automatically when the return value crosses thet.runboundary.toConvexValue(obj)utility that users can wrap their return values with.t.runin convex-test setup: Override the serialization to handleDate→numberconversion (this might belong inconvex-testitself rather than better-convex).Environment
better-convex@0.6.0convex-test@0.0.41convex@1.32.0Related
This is a follow-up to #93 which fixed
.returning()with nullable timestamps andfindFirstreturningnull. That PR fixed the production ORM behavior, but this serialization issue remains specifically in theconvex-testtesting context.