Worker unable to pass data to a Workflow

For Workers & Pages, what is the name of the domain?

n/a

What is the error number?

n/a

What is the error message?

n/a

What is the issue or error you’re encountering

When creating a workflow from a worker.

What steps have you taken to resolve the issue?

  1. My worker create my workflow
    const plainWorkflowPayload = JSON.parse(JSON.stringify(workflowPayload));
    const instance = await workflowBinding.create(plainWorkflowPayload);

  2. This is the format (type.ts)
    export type ClarityParams = {
    transcriptId: string;
    transcriptText: string;
    };

  3. I log the payload in the worker log and all my content is there and valid.

  4. The worker successfully create the workflow and I received the instance ID as well as the queue state

  5. In my worfklow, I added a lot that at the start of the workflow:
    First I declare my workflow >
    export class ClarityWorkflow extends WorkflowEntrypoint<Env, ClarityParams> {
    async run(event: WorkflowEvent, step: WorkflowStep) {

Then I log the data >
// — Log Initial State —
try {
const initialStateLog = await step.do(“log_initial_clarity_state”, async () => {
const transcriptSnippet = typeof event.payload?.transcriptText === ‘string’
? event.payload.transcriptText.substring(0, 100) + (event.payload.transcriptText.length > 100 ? “…” : “”)
: “Transcript text not a string or not available”;

    let payloadString = "event.payload is undefined or null";
    let payloadKeys: string[] = [];
    let payloadType = typeof event.payload;
    let eventKeys: string[] = [];
    let eventStringified = "Error stringifying event";

    if (event && typeof event === 'object') {
        try {
            eventKeys = Object.keys(event);
            eventStringified = JSON.stringify(event); // Log the whole event object
        } catch (e:any) {
            eventStringified = `Error stringifying event: ${e.message}`;
        }
    }

    if (event.payload && typeof event.payload === 'object') {
        try {
            payloadString = JSON.stringify(event.payload);
            payloadKeys = Object.keys(event.payload);
        } catch (e: any) {
            payloadString = `Error stringifying event.payload: ${e.message}`;
        }
    } else if (event.payload) {
        payloadString = `event.payload is a primitive or function of type: ${payloadType}`;
    }

    return {
      message: "Clarity workflow initial state captured.",
      debugVersion: "ClarityWorkflow-" + WORKFLOW_VERSION + " tracing",
      instanceId: workflowInstanceId, // This is event.instanceId
      analysisId: currentRunState.analysisId,
      eventObjectKeys: eventKeys, 
      eventObjectStringified: eventStringified, 
      eventPayloadActualType: payloadType,
      eventPayloadIsObjectAndNotNull: typeof event.payload === 'object' && event.payload !== null,
      eventPayloadStringified: payloadString,
      eventPayloadKeys: payloadKeys,
      transcriptIdFromEventPayload: event.payload?.transcriptId,
      transcriptTextFromEventPayloadIsString: typeof event.payload?.transcriptText === 'string',
      transcriptTextSnippet: transcriptSnippet,
      workflowVersion: WORKFLOW_VERSION,
      loadedConfigVersion: loadedConfigVersion || "Not loaded yet or unavailable",
      currentRunState_transcriptId: currentRunState.transcriptId, 
    };
  });
  // ...
} 
// ...

The payload is empty.

Subject: Persistent Empty event.payload in Cloudflare Workflow Despite Valid Payload Sent via workflowBinding.create()

Issue Description:
We are experiencing a persistent issue where the event.payload received by our Cloudflare Workflow (ClarityWorkflow) is an empty object ({}), even though logs from the triggering Worker script confirm that a valid and populated payload object is being passed to the workflowBinding.create() method. This occurs consistently, even when attempting to pass a minimal string payload.

System Setup:

  1. Triggering Worker (src/utils/workflow-triggers.ts):

    • A Worker script prepares a payload object (intended type ClarityParams).
    • This payload is then sanitized using JSON.parse(JSON.stringify(payloadObject)) to ensure it’s a plain object.
    • The workflow is created using instance = await env.CLARITY_WORKFLOW.create(plainSanitizedPayloadObject);.
    • Logs immediately before this call confirm plainSanitizedPayloadObject contains the expected data.
    // Relevant snippet from src/utils/workflow-triggers.ts
    // workflowPayload is populated correctly with transcriptId and transcriptText
    // (or simpleTestMessage during minimal tests)
    
    const plainWorkflowPayload = JSON.parse(JSON.stringify(workflowPayload));
    
    // Log example (shows correct data here):
    // "[Workflow Trigger Debug vX.Y.Z] Creating clarity workflow (app instanceId: ...). Payload preview: {\n  "transcriptId": "...",\n  "transcriptText": "... (length chars)"\n}"
    // or for minimal test:
    // "[Workflow Trigger Debug vX.Y.Z] Creating clarity workflow (app instanceId: ...). Payload preview: {\n  "simpleTestMessage": "Hello Workflow"\n}"
    
    const instance = await env.CLARITY_WORKFLOW.create(plainWorkflowPayload); 
    
  2. Payload Type Definition (src/types.ts):
    The intended payload structure for ClarityWorkflow:

    export type ClarityParams = {
      transcriptId: string;
      transcriptText: string;
    };
    

    (For minimal testing, this was temporarily changed to export type ClarityParams = { simpleTestMessage: string; };)

  3. Workflow Definition (src/workflows/clarity-workflow.ts):

    • The workflow is defined as export class ClarityWorkflow extends WorkflowEntrypoint<Env, ClarityParams>.
    • The run method signature is async run(event: WorkflowEvent<ClarityParams>, step: WorkflowStep).

Problem Encountered in Workflow:
Despite the triggering Worker sending a populated payload, the event.payload within the ClarityWorkflow.run() method is consistently an empty object ({}).

Diagnostic Logging in Workflow (at the start of run()):

    // --- Log Initial State (snippet from src/workflows/clarity-workflow.ts) ---
    try {
      const initialStateLog = await step.do("log_initial_clarity_state", async () => {
        // ... (setup for payloadString, payloadKeys, etc.) ...
        let eventKeys: string[] = [];
        let eventStringified = "Error stringifying event";

        if (event && typeof event === 'object') {
            try {
                eventKeys = Object.keys(event);
                eventStringified = JSON.stringify(event); // Log the whole event object
            } catch (e:any) { /* ... */ }
        }
        if (event.payload && typeof event.payload === 'object') {
            try {
                payloadString = JSON.stringify(event.payload);
                payloadKeys = Object.keys(event.payload);
            } catch (e: any) { /* ... */ }
        }
        // ... (other fields for the log object) ...
        return {
          message: "Clarity workflow initial state captured.",
          // debugVersion uses package.json version, e.g., "ClarityWorkflow-AppVersion-1.0.312-Debug-v0.3"
          debugVersion: "ClarityWorkflow-AppVersion-" + packageJson.version + "-Debug-v0.3", 
          instanceId: event.instanceId,
          eventObjectKeys: eventKeys, 
          eventObjectStringified: eventStringified, // Shows {"payload":{}, ...}
          eventPayloadActualType: typeof event.payload,
          eventPayloadIsObjectAndNotNull: typeof event.payload === 'object' && event.payload !== null,
          eventPayloadStringified: payloadString, // Consistently shows "{}"
          eventPayloadKeys: payloadKeys, // Consistently shows []
          // Fields for accessing expected data (all show null/false/unavailable):
          transcriptIdFromEventPayload: event.payload?.transcriptId,
          transcriptTextFromEventPayloadIsString: typeof event.payload?.transcriptText === 'string',
          // For minimal test:
          // simpleMessageFromPayload: (event.payload as ClarityParams)?.simpleTestMessage,
        };
      });
    } 

Consistent Log Output from Workflow:
The initialStateLog from the workflow consistently shows:

  • eventObjectStringified: {"payload":{},"timestamp":"...","instanceId":"...","workflowName":"..."}
  • eventPayloadStringified: {}
  • eventPayloadKeys: []
  • Attempts to access properties like event.payload.transcriptId or event.payload.simpleTestMessage yield undefined.

Bare Minimum Test Case:
To rule out issues with payload complexity or size, we performed a minimal test:

  1. Modified ClarityParams to type ClarityParams = { simpleTestMessage: string; };.
  2. Sent a payload like { simpleTestMessage: "Hello Workflow" } from the trigger.
  3. Result: event.payload in the workflow remained an empty object ({}). The simpleTestMessage was not received.

Consequences:
The workflow fails when it attempts to use the expected data from event.payload (e.g., event.payload.transcriptText), as these properties are undefined. Example error: NonRetryableError: transcriptText must be a string for encryption. Received type: undefined.

Summary of Checks:

  • Payload is correctly populated in the triggering Worker before workflowBinding.create().
  • Code versions (from package.json and internal workflow constants) are correctly reflected in logs, confirming deployments are live.
  • The payload object is sanitized with JSON.parse(JSON.stringify(...)) before being passed to create().
  • The WorkflowEntrypoint generic type P matches the type of the payload object.
  • The issue persists even with a minimal, single-string payload.

We believe the data is being lost or incorrectly processed during the handoff by workflowBinding.create() or during deserialization before the workflow’s run method is invoked. The problem appears to be at the platform level.

Please advise on potential causes or further diagnostic steps.

What are the steps to reproduce the issue?

Just try to pass data to a workflow from a worker.

I don’t see you passing the payload to create correctly?

Per Events and parameters · Cloudflare Workflows docs - you should be passing the payload to the params property in an object to create - e.g.

    let instance = await env.MY_WORKFLOW.create({
      id: await crypto.randomUUID(),
      params: someEvent
    });

Instead, you (incorrectly) have:

const instance = await env.CLARITY_WORKFLOW.create(plainWorkflowPayload); 

This topic was automatically closed 15 days after the last reply. New replies are no longer allowed.