can't get workflows to run reliably using cron. anyone experiencing the same thing?
can't get workflows to run reliably using cron. anyone experiencing the same thing?


Errored status.wrangler dev . This is a simplified version of my workflow/DO:
internal error; reference = 4t7lk8kksul8hag46prmnndt

setWebSocketAutoResponse , but I don't think I can access the DO. instance.terminate() isn’t implemented in local dev. I figured restarting the server would clear everything, but even after a restart the workflow instance still seems to persist.wrangler dev will create a .wrangler/state directory where the command was run. You can also change this if you'd like!terminate() is intended to terminate the instance, and although it is not supported yet in dev, it still wouldn't clear the workflow instance state. .wrangler/state/workflows there will be 3 storage files (.sqlite, .sqllite-wal and .sqlite-shm) for each created workflow (the file names are not related to the workflow instance ids, so it is complicated to know which ones to delete). If you really want to run a workflow instance with the id equal to one that already ran, your best option is to delete the files under that directory and re-run the workflow instance.introspectWorkflow should be done at the start of the test (you can think of doing introspectWorkflow where you mock other APIs and so on) - intercepted workflows with DOs should just work (if you want to mock/intercept the calls between the two, let me know)
cron it seems to do it from other geographic locations. I have a security rule to block all traffic to the worker that's not from the United States and it seems that, as of recently, my cron-scheduled workflows are being instantiated outside of the United States in Poland or Singapore which is causing them to be blocked by the security rules.import { WorkflowEntrypoint, WorkflowStep, WorkflowEvent, DurableObject } from 'cloudflare:workers';
import { ActionEvent } from '../types/events';
export class Portal extends DurableObject<Env> {
constructor(ctx: DurableObjectState, env: Env) {
super(ctx, env);
console.log('Initialising portal Durable Object');
}
async test(): string {
return "Hello!";
}
}
export class ActionWorkflow extends WorkflowEntrypoint<Env, ActionEvent> {
async run(params: WorkflowEvent<ActionEvent>, step: WorkflowStep) {
const event = params.payload;
const portalIdString = event.portal_id.toString();
console.log('Starting workflow', event);
const portal = this.env.PORTAL.getByName(portalIdString);
const test = await portal.test();
await step.do('test', async () => {
console.log(test);
});
}
}const portalResponse = await step.do('get-portal-response', async () => {
const portal = this.env.PORTAL.getByName(portalIdString);
return await portal.test();
});const error = await stub
.sendEvent({
type: "capacity-allocated",
payload: null
})
.catch((error) => {
console.error(
`[drainWaiting] Unable to send capacity-allocated event to ${waiting.instance_id}`,
error
)
return error as Error
})
if (!error) {
// Success! Remove from waiting queue
this.dequeueWaitingRun(waiting.instance_id)
console.log(
`[drainWaiting] Successfully sent event and removed ${waiting.instance_id} from waiting queue`
)
const new_status = await stub.status()
console.log(
`[drainWaiting] New status for ${waiting.instance_id} after sending event: ${new_status.status}`
)const new_status = await stub.status()
console.log(
`[drainWaiting] New status for ${waiting.instance_id} after sending event: ${new_status.status}`
)let status = waiting
let attempts = 0
while (status === waiting) {
await stub.sendEvent
status = await stub.status
attempts++
}
console.log("Finally lol")let attempts = 0
let workflowHandled = false
while (attempts < 5 && !workflowHandled) {
attempts++
// Send the event
const error = await stub
.sendEvent({
type: "capacity-allocated",
payload: null
})
.catch((error) => {
console.error(
`[drainWaiting] Unable to send capacity-allocated event to ${waiting.instance_id} (attempt ${attempts}/5)`,
error
)
return error as Error
})
// Wait 2.5 seconds then check status
await new Promise((resolve) => setTimeout(resolve, 2500))
const status = await stub.status()
console.log(
`[drainWaiting] Status check for ${waiting.instance_id} after attempt ${attempts}: ${status.status}`
){ "source": { "level": "error", "message": "run" }, "dataset": "cloudflare-workers", "timestamp": "2025-09-17T14:51:22.136Z", "$workers": { "diagnosticsChannelEvents": [], "truncated": false, "event": { "rpcMethod": "run" }, "scriptName": "worker-insight-staging", "outcome": "exception", "eventType": "rpc", "entrypoint": "FetchAdInsightsWorkflow", "scriptVersion": { "id": "f85a34a5-8a00-4692-b0bc-4c80b91fe8ef" }, "executionModel": "stateless", "requestId": "PUFWDN8JVB9SKDFI", "wallTimeMs": 463, "cpuTimeMs": 3 }, "$metadata": { "id": "01K5C2H8MR4QRA6B5HE0KF1FBX", "requestId": "PUFWDN8JVB9SKDFI", "trigger": "default.run", "service": "worker-insight-staging", "level": "error", "error": "run", "message": "run", "account": "e97e3fed722428f4d726062eae9aa766", "type": "cf-worker-event", "fingerprint": "34bb94fedcdf1b63ffea70b314aa379b", "origin": "rpc", "messageTemplate": "run" }, "links": [] }const defaultConfig: WorkflowStepConfig = {
retries: {
limit: 0,
delay: 0,
backoff: 'constant',
},
timeout: '3 minutes',
}