i am able to see the top level errors' messages on that page which i thought it would work the same
i am able to see the top level errors' messages on that page which i thought it would work the same for you sorry about that
workflows-starter@0.0.1 deploy
wrangler deploy
do something with ids run multiple times even tho it doesn't fail or anything

fetch(req: Request, env: Env): Promise<Response> for the root, and the favicon requests that explains why each step is being called multiple times.await env.WORKFLOW_NAME.create() with an ambiguous "internal error", whereas some succeeded."Error: internal error" as far as I can tell.Promise.allif i recall correctly.run function after 2 steps if it doesn't need to progress further -- not an error, just a situation where it doesn't need to continue. I'm not throwing an error, just returning an object with some data, but for some reason it seems like this is still showing in the workflow's worker logs as an "Error" (but it shows up correctly in the Workflow logs as "Completed" -- no error). Is there something specific I need to be returning from the run function so it doesn't register as an error/Exception in the Worker?step.do for retries but then I could really quickly hit 1024 steps limit. Maybe I could invoke separate workflow in the inner loop to just handle processing the event? But then my generateEventSummary might throw 429 error. I guess sending queue message for every event and handling it in separate worker might be a better approach? What would be the "idiomatic" CF approach? Thanks!.terminate() method on a workflow instance implemented at the moment?// src/workers/my.worker.ts
import { MyWorkflow } from "../workflows/my.workflow";
export {
MyWorkflow
};
type Bindings = {
MY_WORKFLOW: Workflow;
};
const app = new Hono<{ Bindings: Bindings }>();
app.post('/', async (c) => {
return c.env.MY_WORKFLOW.create(..);
})
export default {
fetch: app.fetch,
};do something with idsfetch(req: Request, env: Env): Promise<Response>await env.WORKFLOW_NAME.create()"Error: internal error"[32mdetails:[0m { "request_id": "ae65c446-f13d-4f95-98b8-ed25ccfa47e6", "fileId": "a386a543-91f9-4a78-af85-257ee4ba2728", "error": "internal error", "stack": "Error: internal error\n at callFetcher (cloudflare-internal:workflows-api:24:15)\n at async WorkflowImpl.create (cloudflare-internal:workflows-api:78:24)\n at async fileUploadService (main.js:919559:11)\n at async fileUploadController (main.js:919663:32)\n at async dispatch (main.js:1116:21)\n at async main.js:859416:9\n at async dispatch (main.js:1116:21)\n at async main.js:859416:9\n at async dispatch (main.js:1116:21)\n at async main.js:967997:5" }",const cats = await Promise.all(catList.map(cat => step.do(`get cat: ${cat}`, () => env.KV.get(cat))));runrunstep.dogenerateEventSummary.terminate()export default {
async fetch(req: Request, env: Env): Promise<Response> {
let instance = await env.DATA_WORKFLOW.create();
return Response.json({
id: instance.id,
details: await instance.status(),
});
},
};async run(event: WorkflowEvent<Params>, step: WorkflowStep) {
const storageKey = `instructions-${event.instanceId}.json`;
const defaultConfig = {retries: { limit: 1, delay: 1000 }};
try {
const ids = await step.do('download ids', defaultConfig, async () => {
//
});
await step.do('do something with ids', defaultConfig, async () => {
//
});
await step.do('do something with ids', defaultConfig, async () => {
//
});
// Cleanup after successful completion
await this.env.TEMP_STORAGE.delete(storageKey);
} catch (error) {
// Cleanup on failure
await this.env.TEMP_STORAGE.delete(storageKey);
throw new NonRetryableError("Unknown error");
}
let workflow = await this.env.DATA_WORKFLOW.get(event.instanceId);
await workflow.terminate();
}// ✅ Good: steps that are dynamically named are constructed in a deterministic way.
// In this case, `catList` is a step output, which is stable, and `catList` is
// traversed in a deterministic fashion (no shuffles or random accesses) so,
// it's fine to dynamically name steps (e.g: create a step per list entry).
let catList = await step.do("get cat list from KV", async () => {
return await env.KV.get("cat-list");
});
for (const cat of catList) {
await step.do(`get cat: ${cat}`, async () => {
return await env.KV.get(cat);
});
}await step.do("process-events", async () => {
const eventsGroupedBySomething = [[], [], [], [], [], []]; // potentially ~10 groups with 100s of events each
for (const events of eventsGroupedBySomething) {
for (let i = 0; i < events.length; i++) {
const event = events[i]!;
const { embedding, summary } = await generateEventSummary(event);
await db
.insert(schema.eventVector)
.values({ id: nanoid(), eventId: event.id, embedding, summary });
}
}
});