arbalada
arbalada3h ago

false positive "Date.now() isn't currently supported within workflows." when testing workflow

I'm hitting a → Date.now() isn't currently supported within workflows. error, even though there's no call to Date.now() in my code the test is this:
/// <reference types="vite/client" />


import workflowComponentSchema from '../../node_modules/@convex-dev/workflow/src/component/schema'
export const workflowComponentModules = import.meta.glob(
'../../node_modules/@convex-dev/workflow/src/component/**/!(*.*.*)*.*s',
)

test('sync', async () => {
const t = convexTest(schema)
t.registerComponent('workflow', workflowComponentSchema, workflowComponentModules)

// .. some setup

await t.mutation(internal.services.sync.startWorkflow, {
userId,
repoId,
})
})
/// <reference types="vite/client" />


import workflowComponentSchema from '../../node_modules/@convex-dev/workflow/src/component/schema'
export const workflowComponentModules = import.meta.glob(
'../../node_modules/@convex-dev/workflow/src/component/**/!(*.*.*)*.*s',
)

test('sync', async () => {
const t = convexTest(schema)
t.registerComponent('workflow', workflowComponentSchema, workflowComponentModules)

// .. some setup

await t.mutation(internal.services.sync.startWorkflow, {
userId,
repoId,
})
})
and start workflow is this:
export const startWorkflow = internalMutation({
args: {
userId: v.id('users'),
repoId: v.id('repos'),
},
async handler(ctx, args) {
let savedRepo = await ctx.db.get(args.repoId)
if (!savedRepo) return err('repo not found')

let startSync = new Date().toISOString()

await workflow.start(
ctx,
internal.services.sync.backfillRepoWorkflow,
{
userId: args.userId,
repoId: savedRepo._id,
},
{
onComplete: internal.services.sync.finishBackfill,
context: {
repoId: savedRepo._id,
backfillStartedAt: startSync,
} satisfies FinishBackfillArgs['context'],
},
)
},
})
export const startWorkflow = internalMutation({
args: {
userId: v.id('users'),
repoId: v.id('repos'),
},
async handler(ctx, args) {
let savedRepo = await ctx.db.get(args.repoId)
if (!savedRepo) return err('repo not found')

let startSync = new Date().toISOString()

await workflow.start(
ctx,
internal.services.sync.backfillRepoWorkflow,
{
userId: args.userId,
repoId: savedRepo._id,
},
{
onComplete: internal.services.sync.finishBackfill,
context: {
repoId: savedRepo._id,
backfillStartedAt: startSync,
} satisfies FinishBackfillArgs['context'],
},
)
},
})
I see that there's a new Date() call, but if I just put an empty string I still have this error. I'm using bun with vitest, setup as close as possible as documented.
No description
1 Reply
arbalada
arbaladaOP2h ago
alright here's a full example that causes the error:
// test file
/// <reference types="vite/client" />

import { internal } from '@convex/_generated/api'
import schema from '@convex/schema'
import { convexTest } from 'convex-test'
import { test } from 'vitest'

import workflowComponentSchema from '../../node_modules/@convex-dev/workflow/src/component/schema'
export const workflowComponentModules = import.meta.glob(
'../../node_modules/@convex-dev/workflow/src/component/**/!(*.*.*)*.*s',
)

test('sync', async () => {
const t = convexTest(schema)
t.registerComponent('workflow', workflowComponentSchema, workflowComponentModules)

await t.mutation(internal.services.sync.startHelloWorldWorkflow, {})
})
// test file
/// <reference types="vite/client" />

import { internal } from '@convex/_generated/api'
import schema from '@convex/schema'
import { convexTest } from 'convex-test'
import { test } from 'vitest'

import workflowComponentSchema from '../../node_modules/@convex-dev/workflow/src/component/schema'
export const workflowComponentModules = import.meta.glob(
'../../node_modules/@convex-dev/workflow/src/component/**/!(*.*.*)*.*s',
)

test('sync', async () => {
const t = convexTest(schema)
t.registerComponent('workflow', workflowComponentSchema, workflowComponentModules)

await t.mutation(internal.services.sync.startHelloWorldWorkflow, {})
})
// workflow

// Simple hello world workflow
export const helloWorldWorkflow = workflow.define({
args: {
name: v.optional(v.string()),
},
async handler(step, args): Promise<void> {
await step.runAction(internal.services.sync.helloWorldAction, {
name: args.name ?? 'World',
})
},
})

// Simple hello world action
export const helloWorldAction = internalAction({
args: {
name: v.string(),
},
async handler(ctx, args) {
logger.info(`Hello, ${args.name}!`)
return ok(`Hello, ${args.name}!`)
},
})

// Mutation to start the hello world workflow
export const startHelloWorldWorkflow = internalMutation({
args: {
name: v.optional(v.string()),
},
async handler(ctx, args) {
await workflow.start(ctx, internal.services.sync.helloWorldWorkflow, {
name: args.name,
})
return ok('Hello world workflow started')
},
})
// workflow

// Simple hello world workflow
export const helloWorldWorkflow = workflow.define({
args: {
name: v.optional(v.string()),
},
async handler(step, args): Promise<void> {
await step.runAction(internal.services.sync.helloWorldAction, {
name: args.name ?? 'World',
})
},
})

// Simple hello world action
export const helloWorldAction = internalAction({
args: {
name: v.string(),
},
async handler(ctx, args) {
logger.info(`Hello, ${args.name}!`)
return ok(`Hello, ${args.name}!`)
},
})

// Mutation to start the hello world workflow
export const startHelloWorldWorkflow = internalMutation({
args: {
name: v.optional(v.string()),
},
async handler(ctx, args) {
await workflow.start(ctx, internal.services.sync.helloWorldWorkflow, {
name: args.name,
})
return ok('Hello world workflow started')
},
})
dependencies used: - "vitest": "^3.2.4" - "convex-test": "^0.0.38", - "convex": "^1.27.0", - "convex-helpers": "^0.1.104", - "@convex-dev/aggregate": "^0.1.23", - "@convex-dev/auth": "^0.0.88", - "@convex-dev/migrations": "^0.2.9", - "@convex-dev/react-query": "0.0.0-alpha.11", - "@convex-dev/workflow": "^0.2.6", - "@convex-dev/workpool": "^0.2.18", - "@edge-runtime/vm": "^5.0.0", if you need more info I'll happily provide it

Did you find this page helpful?