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?
-
My worker create my workflow
const plainWorkflowPayload = JSON.parse(JSON.stringify(workflowPayload));
const instance = await workflowBinding.create(plainWorkflowPayload); -
This is the format (type.ts)
export type ClarityParams = {
transcriptId: string;
transcriptText: string;
}; -
I log the payload in the worker log and all my content is there and valid.
-
The worker successfully create the workflow and I received the instance ID as well as the queue state
-
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:
-
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);
- A Worker script prepares a payload object (intended type
-
Payload Type Definition (
src/types.ts
):
The intended payload structure forClarityWorkflow
:export type ClarityParams = { transcriptId: string; transcriptText: string; };
(For minimal testing, this was temporarily changed to
export type ClarityParams = { simpleTestMessage: string; };
) -
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)
.
- The workflow is defined as
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
orevent.payload.simpleTestMessage
yieldundefined
.
Bare Minimum Test Case:
To rule out issues with payload complexity or size, we performed a minimal test:
- Modified
ClarityParams
totype ClarityParams = { simpleTestMessage: string; };
. - Sent a payload like
{ simpleTestMessage: "Hello Workflow" }
from the trigger. - Result:
event.payload
in the workflow remained an empty object ({}
). ThesimpleTestMessage
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 tocreate()
. - The
WorkflowEntrypoint
generic typeP
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.