Hi all,

I’m new to Epicor, and we’ve recently been having a few issues. Lately, a service that we wrote that retrieves and creates orders has suddenly broken.

I’ve noticed that in the stack trace it appears to be calling a BPM Sales Order update that does not exist. Nothing has changed on the application that would cause a problem. However, recently we had some other issues and an Epicor support person redeployed our ClientDeployment folder and redeployed our Server directory on the web server.

I’m sorry if this information isn’t helpful. Please let me know what I could include to help shed light on what the problem might be. Has anyone had any similar issues?


Error Getting Orders. Error Message: Server Side Error

Server Side Exception
Description: Index was outside the bounds of the array.
Program: Epicor.ServiceModel.dll
Method: Entry
Original Exception Type: IndexOutOfRangeException
Server Trace Stack: at Epicor.Utilities.StringExtensions.Entry(String srcString, Int32 index, String delimiter)
at Erp.Internal.Lib.XAP05.Do_1100(String In_ParmList)
at Erp.Internal.Lib.XAP05._XAP05(Int32 In_AlertNum, String In_ParmList, String& VContinue)
at Erp.Triggers.OrderHed.WriteTrigger.Write(OrderHed OrderHed, OrderHed OldOrderHed)
at Ice.Triggers.TriggerQueue.ExecuteWriteTrigger(IceDataContext context, LinqRow modifiedRecord, LinqRow originalRecord)
at Ice.Triggers.TriggerQueue.RunWriteTriggerInNewLevel(IceDataContext context, LinqRow modifiedRecord, LinqRow originalRecord, Boolean forAddedRow)
at Ice.Triggers.TriggerQueue.<>c__DisplayClass6.b__4()
at Ice.Triggers.TriggerQueue.RunAtNewLevel(Func1 buildTriggerRunState, Action action) at Ice.Triggers.TriggerQueue.RunTriggers(IceDataContext context) at Ice.IceDataContext.RunUntilAllTriggersHaveExecuted() at Ice.Triggers.TriggerQueue.RunAtNewLevel(Func1 buildTriggerRunState, Action action)
at Ice.IceDataContext.Validate[TLinqRow](TLinqRow row)
at Ice.TablesetBound3.CreateRow(IceDataContext dc, Int32 tableNum, IIceTable tbl, IceRow newTablesetRow, TablesetProfilingCollector parentTraceCollector) at Ice.TablesetBound3.WriteTable(IceDataContext context, Int32 tableIndex, IIceTable table, TablesetProfilingCollector parentTraceCollector)
at Ice.TablesetBound3.InnerUpdate(IceDataContext context, TFullTableset tableset) at Erp.Services.BO.SalesOrderSvc.Update(SalesOrderTableset& ds) at Epicor.Customization.Bpm.BOA00587C0CBD7466FB9707153BB790703.UpdateImpl.ExecuteBase() in c:\inetpub\wwwroot\Epicor10\Server\BPM\Builds\BO\SalesOrder.Update.197.A226673E23FC4A90BD203CBEC7DF3C60\SalesOrder.Update.cs:line 315 at Epicor.Customization.Bpm.MethodCustomizationBase1.ExecuteDirectives()
at Epicor.Customization.Bpm.CustomizationBase.ExecuteCore()
at Epicor.Customization.Bpm.BOA00587C0CBD7466FB9707153BB790703.UpdateImpl.Execute(SalesOrderTableset& ds) in c:\inetpub\wwwroot\Epicor10\Server\BPM\Builds\BO\SalesOrder.Update.197.A226673E23FC4A90BD203CBEC7DF3C60\SalesOrder.Update.cs:line 307
at Erp.Services.BO.SalesOrderSvcFacade.Update(SalesOrderTableset& ds)
at Erp.Services.BO.SalesOrderSvc.MasterUpdate(Boolean lcheckForResponse, String cTableName, Int32 iCustNum, Int32 iOrderNum, Boolean lweLicensed, Boolean& lContinue, String& cResponseMsg, String& cDisplayMsg, String& cCompliantMsg, String& cResponseMsgOrdRel, SalesOrderTableset& ds)
at Erp.Services.BO.SalesOrderSvcFacade.MasterUpdate(Boolean lcheckForResponse, String cTableName, Int32 iCustNum, Int32 iOrderNum, Boolean lweLicensed, Boolean& lContinue, String& cResponseMsg, String& cDisplayMsg, String& cCompliantMsg, String& cResponseMsgOrdRel, SalesOrderTableset& ds)
at SyncInvokeMasterUpdate(Object , Object[] , Object[] )
at System.ServiceModel.Dispatcher.SyncMethodInvoker.Invoke(Object instance, Object[] inputs, Object[]& outputs)
at Epicor.Hosting.OperationBoundInvoker.Invoke(Object instance, Func`2 func)
at Epicor.Hosting.Wcf.EpiOperationInvoker.Invoke(Object instance, Object[] inputs, Object[]& outputs)
at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage11(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)

If the BPM does not exist, try creating one, save it, and delete it. It should clear the code on the server.

Thanks for the reply! I just gave this a shot, and I still had the same result.

Hopefully that service you mention uses Epicor BO’s and not direct SQL… if you guys are fiddling with SQL, you’re gonna have beaucoup problems. Never directly add, delete, or update an Epicor record from SQL!

Also, regardless of whether you have a BPM or not, the write triggers will fire. Correct me if I’m wrong @Bart_Elia or @josecgomez

Are you multi-company? That BPM should exist somewhere… I wonder if its a cross company BPM or a Data Directive? Though it looks like your error is happening WAY at the write trigger level leads me to believe you are passing bad data.
What does the call that causes this look like?

1 Like

Its failing at

Epicor.Utilities.StringExtensions.Entry(String srcString, Int32 index, String delimiter)

In your BPM you are using the String Extension, and you are saying something like index 2, delimited by ~ or , or | and it’s throwing an error because my~coolstring has only 0 and 1. Check your data, check your method.

This is similar to when people try to use “MyString”.SubString(0, 20) and C# throws an exception because the string does not have 20 characters. The fail to evaluate “MyString”.Length

Your field may even be empty or null. Epicor has a NumEntries helper you should use to determine the length

int Count = myList.NumEntries("~");

Even Epicor uses it:

for (ix = 1; ix <= SelectedDepts.NumEntries("~"); ix++) { // do work }

Just for the record for anyone else this is how Entry Helper works examples:

string theItem = myList.Entry(1);
string theItem = myList.Entry(1, "~");

// You can also add new items into the list into a given index
string newList = myList.Entry("NewValue", 0);
string newList = myList.Entry("NewValue", 0, "~");

It’s probably doing a .Split() behind the scenes and your error is no different then when you are trying to access an Array index that’s out of range.

Likewise, what Jose asked, you may have a BPM in a different Company so it wouldnt be visible unless you go to the lower company.

Perhaps its a “Data Directive” In-Transaction? (Judging based on the InnerUpdate Exception)

This is the call that is failing:
salesOrderBO.MasterUpdate(true, "OrderHed", cds.Customer[0].CustNum, 0, false, out IContinue, out cResponseMsg, out cDisplayMsg, out cComplaintMsg, out cResponseMsgOrderRel, sods);

However I logged the data passed, and we’re sending all of the correct data. Nothing has changed, and this only became a problem after working with Epicor support. After the deploy, this call never finishes.

We are multi-company, but what is strange to me is that it’s “failing” at this file:

…but that file doesn’t exist at that location. There is no update directory with that number.

I don’t know if that’s expected or not. Maybe it temporarily creates those files? Thanks for helping, I’m very lost at the moment.

I guess I don’t know what the real problem is. So you’re saying this issue will occur even with no BPMs? And no, in this case we’re not directly modifying the database. But I should double check that the previous programmer wasn’t doing that elsewhere. I’m curious, if all of the fields are properly updated, what is the problem with writing to the database for Epicor. I’m asking because we had planned to do so in a future project. What issues does it cause?

According to support it may void your Maintenance Agreement. Try to avoid it, so you can benefit of the Hooks & Triggers. If its a UD Table or your own customfield_c, use your best judgement.

There is alot of logic behind every field updated, for example by just Updating a Topic on a HDCase, it also appends it to 2-3 other columns, which you may or may not know.

No, check Data Directives Maintenance - it should be there under one of the Order Tables. A BPM is definitely there somewhere, I am just saying that the programmer may have had not so perfect code - probably programmed with the expectation that a value will always exist.

This definitely seems to Epicor calling it behind the scenes. I was able to check the data, and everything is there. Again the code or the data passed hasn’t been changed at all, which led me to think it has something to do with the server being redeployed. Do you think any BPMs were lost in this process?

Again, sorry if I’m not making much sense. I’m still very green with Epicor. I appreciate your reply!

You can find Directive Update via the Menu Search and try recompiling all your BPMs.

1 Like

I see what you mean. This is definitely a lot of code to take over, I’m trying to not make assumptions on the data available. However, in this case I was able to verify what’s being passed in, at least at the application level. I honestly don’t know about data within Epicor, and I’ve found it very confusing how Epicor manages it’s internal state. I’ll check the Data Directives Maintenance and see if I can find something. Thank you!


Then just click Search it’ll show all the ones you have.