diff --git a/apps/sim/background/schedule-execution.ts b/apps/sim/background/schedule-execution.ts index d51e2f290ac..c4704585f5b 100644 --- a/apps/sim/background/schedule-execution.ts +++ b/apps/sim/background/schedule-execution.ts @@ -208,8 +208,11 @@ async function runWorkflowExecution({ const mergedStates = mergeSubblockState(blocks) + // Use workflow creator's userId for personal env vars (not the billing actor) + // This ensures pre-checks match the execution behavior in execution-core.ts + const envVarUserId = workflowRecord.userId || actorUserId const { personalEncrypted, workspaceEncrypted } = await getPersonalAndWorkspaceEnv( - actorUserId, + envVarUserId, workflowRecord.workspaceId || undefined ) diff --git a/apps/sim/lib/workflows/executor/execution-core.ts b/apps/sim/lib/workflows/executor/execution-core.ts index 1096aa16237..1c5aa7c8160 100644 --- a/apps/sim/lib/workflows/executor/execution-core.ts +++ b/apps/sim/lib/workflows/executor/execution-core.ts @@ -152,8 +152,13 @@ export async function executeWorkflowCore( // Merge block states const mergedStates = mergeSubblockState(blocks) + // Use workflow creator's userId for personal env vars (not the billing actor) + // This ensures that {{variable}} references in the workflow resolve to the + // creator's personal environment variables, not the workspace billing account's. + // For shared workspace workflows, workspace-scoped env vars are recommended. + const envVarUserId = workflow.userId || userId const { personalEncrypted, workspaceEncrypted, personalDecrypted, workspaceDecrypted } = - await getPersonalAndWorkspaceEnv(userId, providedWorkspaceId) + await getPersonalAndWorkspaceEnv(envVarUserId, providedWorkspaceId) // Use encrypted values for logging (don't log decrypted secrets) const variables = EnvVarsSchema.parse({ ...personalEncrypted, ...workspaceEncrypted })