feel like i must be doing something

feel like i must be doing something stupid but trying to run the workflows-starter and getting a 500 when trying to create a workflow:
[wrangler:inf] GET / 500 Internal Server Error (48ms)
[wrangler:inf] GET /favicon.ico 404 Not Found (2ms)
id null
creating new instance RpcStub {}
[wrangler:err] TypeError: Cannot destructure property 'id' of 'undefined' as it is undefined.
at async Object.fetch (file:///Users/srb/projects/elater-cf-workflow/workflows-starter/src/index.ts:84:18)
at async jsonError (file:///Users/srb/projects/elater-cf-workflow/workflows-starter/node_modules/wrangler/templates/middleware/middleware-miniflare3-json-error.ts:22:10)
at async drainBody (file:///Users/srb/projects/elater-cf-workflow/workflows-starter/node_modules/wrangler/templates/middleware/middleware-ensure-req-body-drained.ts:5:10)
[wrangler:inf] GET / 500 Internal Server Error (48ms)
[wrangler:inf] GET /favicon.ico 404 Not Found (2ms)
id null
creating new instance RpcStub {}
[wrangler:err] TypeError: Cannot destructure property 'id' of 'undefined' as it is undefined.
at async Object.fetch (file:///Users/srb/projects/elater-cf-workflow/workflows-starter/src/index.ts:84:18)
at async jsonError (file:///Users/srb/projects/elater-cf-workflow/workflows-starter/node_modules/wrangler/templates/middleware/middleware-miniflare3-json-error.ts:22:10)
at async drainBody (file:///Users/srb/projects/elater-cf-workflow/workflows-starter/node_modules/wrangler/templates/middleware/middleware-ensure-req-body-drained.ts:5:10)
will thread the rest of my src code. is there a specific url you're supposed to hit or something?
3 Replies
srb
srbOP2mo ago
this is again just from creating the workflows-starter, my src/index.ts is this default function:
export default {
async fetch(req: Request, env: Env): Promise<Response> {
let url = new URL(req.url);

if (url.pathname.startsWith('/favicon')) {
return Response.json({}, { status: 404 });
}

let id = url.searchParams.get('instanceId');
console.log('id', id);
if (id) {
let instance = await env.MY_WORKFLOW.get(id);
return Response.json({
status: await instance.status(),
});
}

console.log('creating new instance', await env.MY_WORKFLOW.create);
let instance = await env.MY_WORKFLOW.create();
console.log('instance', instance);
return Response.json({
id: instance.id,
details: await instance.status(),
});
},
};
export default {
async fetch(req: Request, env: Env): Promise<Response> {
let url = new URL(req.url);

if (url.pathname.startsWith('/favicon')) {
return Response.json({}, { status: 404 });
}

let id = url.searchParams.get('instanceId');
console.log('id', id);
if (id) {
let instance = await env.MY_WORKFLOW.get(id);
return Response.json({
status: await instance.status(),
});
}

console.log('creating new instance', await env.MY_WORKFLOW.create);
let instance = await env.MY_WORKFLOW.create();
console.log('instance', instance);
return Response.json({
id: instance.id,
details: await instance.status(),
});
},
};
plus this workflow class:
export class MyWorkflow extends WorkflowEntrypoint<Env, Params> {
async run(event: WorkflowEvent<Params>, step: WorkflowStep) {
// Can access bindings on `this.env`
// Can access params on `event.payload`

const files = await step.do('my first step', async () => {
// Fetch a list of files from $SOME_SERVICE
return {
inputParams: event,
files: [
'doc_7392_rev3.pdf',
'report_x29_final.pdf',
'memo_2024_05_12.pdf',
'file_089_update.pdf',
'proj_alpha_v2.pdf',
'data_analysis_q2.pdf',
'notes_meeting_52.pdf',
'summary_fy24_draft.pdf',
],
};
});

const apiResponse = await step.do('some other step', async () => {
let resp = await fetch('https://api.cloudflare.com/client/v4/ips');
return await resp.json<any>();
});

await step.sleep('wait on something', '1 minute');

await step.do(
'make a call to write that could maybe, just might, fail',
// Define a retry strategy
{
retries: {
limit: 5,
delay: '5 second',
backoff: 'exponential',
},
timeout: '15 minutes',
},
async () => {
// Do stuff here, with access to the state from our previous steps
if (Math.random() > 0.5) {
throw new Error('API call to $STORAGE_SYSTEM failed');
}
}
);
}
}
export class MyWorkflow extends WorkflowEntrypoint<Env, Params> {
async run(event: WorkflowEvent<Params>, step: WorkflowStep) {
// Can access bindings on `this.env`
// Can access params on `event.payload`

const files = await step.do('my first step', async () => {
// Fetch a list of files from $SOME_SERVICE
return {
inputParams: event,
files: [
'doc_7392_rev3.pdf',
'report_x29_final.pdf',
'memo_2024_05_12.pdf',
'file_089_update.pdf',
'proj_alpha_v2.pdf',
'data_analysis_q2.pdf',
'notes_meeting_52.pdf',
'summary_fy24_draft.pdf',
],
};
});

const apiResponse = await step.do('some other step', async () => {
let resp = await fetch('https://api.cloudflare.com/client/v4/ips');
return await resp.json<any>();
});

await step.sleep('wait on something', '1 minute');

await step.do(
'make a call to write that could maybe, just might, fail',
// Define a retry strategy
{
retries: {
limit: 5,
delay: '5 second',
backoff: 'exponential',
},
timeout: '15 minutes',
},
async () => {
// Do stuff here, with access to the state from our previous steps
if (Math.random() > 0.5) {
throw new Error('API call to $STORAGE_SYSTEM failed');
}
}
);
}
}
wrangler.toml is
#:schema node_modules/wrangler/config-schema.json
name = "workflows-starter"
main = "src/index.ts"
compatibility_date = "2024-10-22"

[observability]
enabled = true
head_sampling_rate = 1 # optional. default = 1.

[[workflows]]
# name of your workflow
name = "workflows-starter"
# binding name env.MYWORKFLOW
binding = "MY_WORKFLOW"
# this is class that extends the Workflow class in src/index.ts
class_name = "MyWorkflow"
#:schema node_modules/wrangler/config-schema.json
name = "workflows-starter"
main = "src/index.ts"
compatibility_date = "2024-10-22"

[observability]
enabled = true
head_sampling_rate = 1 # optional. default = 1.

[[workflows]]
# name of your workflow
name = "workflows-starter"
# binding name env.MYWORKFLOW
binding = "MY_WORKFLOW"
# this is class that extends the Workflow class in src/index.ts
class_name = "MyWorkflow"
ohh thank you that worked
skip
skip2mo ago
I'm surprised this bug still exists after a week? Hope it's not stopping people trying out workflows
telliks
telliks2mo ago
Just ran into this as well and wanted to let others know to pass an empty object.
Want results from more Discord servers?
Add your server