Inventory transfer workflow fails during batch job execution

Critical issue with inventory transfer workflows in our D365 10.0.39 environment. The workflow fails consistently when triggered during scheduled batch job execution, but manual workflow execution works perfectly fine. There have been no recent updates to our workflow definition.

The error only appears during the nightly batch run:


Error: Workflow execution failed
InventTransferWorkflow.execute() line 234
Batch task execution terminated
Stack trace: InventTransferOrderLine validation

When we manually submit the same transfer orders through the UI during business hours, they process without any issues. The batch job is configured to run at 2 AM daily to process pending transfers. We’ve verified that the batch job service account has all necessary permissions and the workflow definition hasn’t been modified in over 6 months.

This is blocking our automated inventory rebalancing process across warehouses. Has anyone dealt with batch-specific workflow failures that don’t occur during interactive sessions?

Here’s the complete solution addressing all three key aspects of your issue:

1. Error Appears Only During Scheduled Batch Jobs: The batch execution context lacks the user session state that interactive workflows rely on. Your custom validation code at InventTransferOrderLine is trying to access session-specific data that doesn’t exist in batch mode. You need to modify the validation logic to detect batch execution context and handle it appropriately:


// Add this check in your validation method:
if (xSession::isBatch())
{
    // Use system account validation path
    return this.validateForBatchExecution();
}

2. Manual Workflow Execution Works Fine: This confirms the workflow logic itself is sound, but the execution environment differs. The issue is the RunAs context. When you manually execute, it runs under your user account with full security context. In batch mode, it runs under the batch service account which may lack specific privileges. Grant the batch service account the same security roles as users who normally process transfer orders. Specifically, ensure it has InventTransferOrderMaintain privilege.

3. No Recent Updates to Workflow Definition: Since the workflow definition is stable, the problem is environmental or data-related. The error at line 234 suggests a validation failure on inventory dimensions. During batch execution, the dimension resolution might be hitting uncommitted data or stale cache. Add this to your workflow configuration:


// Force dimension refresh in batch context
InventDim::clearCache();
InventTransferLine.reread();

Complete Resolution:

  1. Modify Custom Validation Code: Update your InventTransferOrderLine validation to handle batch context explicitly. Remove any direct references to userInfo() or curUserId() and replace with a service account check that validates based on data state rather than user permissions.

  2. Fix Transaction Scope: Wrap your validation logic in proper transaction handling for batch mode. The workflow engine manages its own transactions, so your custom code shouldn’t create nested transaction blocks. Remove any ttsbegin/ttscommit in the validation method and let the workflow engine handle transaction boundaries.

  3. Update Batch Job Configuration: Change the batch job execution time to avoid conflicts with inventory close processes. If your inventory close runs at 2 AM, move the transfer workflow batch to 3 AM or later. Also, set the batch job priority to Normal instead of High to prevent it from starving other critical processes.

  4. Add Error Handling: Implement retry logic in your batch job specifically for workflow failures. Configure the batch job to retry failed tasks with a 15-minute delay, allowing any transient locking issues to resolve.

  5. Enable Detailed Logging: Add custom infolog entries in your validation code to capture the exact state when running in batch mode. This will help diagnose any future occurrences.

After implementing these changes, test by manually triggering the batch job during business hours before scheduling it for overnight execution. Monitor the first few overnight runs closely to ensure the issue is fully resolved.


This draft is based on general Microsoft Dynamics 365 knowledge. It has not been verified against your specific version and environment. Practitioners: verify the steps and share your experience below.

The difference between batch and interactive execution contexts is key here. During batch execution, certain session-specific variables and user context information aren’t available. Check if your workflow has any custom X++ code that references userInfo() or curUserId() functions. These will return different values or null during batch execution compared to interactive sessions.

That’s an interesting angle. I reviewed the workflow configuration and there is custom validation code in the InventTransferOrderLine class. It checks user permissions before allowing the transfer. Could this be failing when running under the batch service account context?

Yes, that’s almost certainly your issue. The batch service account might have different security roles than regular users. But there’s another common culprit with inventory transfers in batch mode: database connection context. During batch execution, if your workflow validation code tries to access inventory dimensions or tracking data, it might be hitting a different database connection that doesn’t have the proper isolation level set. This can cause locking issues or transaction scope problems that don’t occur during interactive sessions where the connection context is different. Check if the validation logic queries InventDim or related tables.

I’ve encountered this exact scenario. The problem is likely in how the workflow runtime handles transaction boundaries during batch execution versus interactive mode. In batch mode, transactions are managed differently and if your custom validation code doesn’t properly handle the transaction scope, it can fail. Look for any ttsbegin/ttscommit blocks in your custom workflow code that might be conflicting with the workflow engine’s own transaction management.

Tested this on D365 FO 10.0.32 and adding the xSession::isBatch() check in the InventTransferOrderLine validation method immediately resolved our batch job failures.

Check the Application Event Log on your AOS server during the batch execution window. The error message you’re seeing is probably a wrapper exception, and the underlying cause is logged there. Look for any SQL deadlock errors or timeout exceptions that occur at 2 AM. Batch jobs often encounter different database contention patterns than interactive sessions.

Another consideration: verify that your batch job recurrence settings aren’t causing overlap with other inventory-related batch processes. If another job is locking inventory tables at 2 AM, your workflow batch job will fail on validation. Check the batch job schedule for any conflicts with inventory close, master planning, or other warehouse operations that might create locks on InventTransferTable or related tables during that time window.