Logic hook can't find link name of relation

Hello All,

I'm looking for help with figuring out why a new logic hook works well on my local Sugar instance but does not work in the online instance. This is an after_save logic hook in the RevenueLineItems module that automatically creates/updates records in a custom module called BillingMilestones and then deletes unneeded BillingMilestone records. There is a one-to-many relationship between RevenueLineItems and BillingMilestones. There is also a one-to-many relationship between Opportunities and RevenueLineItems, and an after_save logic hook that updates RevenueLineItems with values from Opportunity on saving an Opportunity.

The new after_save hook that I'm working on is meant to create/update BillingMilestones on saving an Opportunity. This hook has several functions that create/update a BillingMilestone and one function that deletes unneeded BillingMilestones. The functions that create/update records work well. The problem occurs in the function that deletes unneeded records. The last two lines of this function are



Using $GLOBALS['log'] statements, I see that mark_deleted() runs successfully, but an error is thrown during the execution of the save() statement. In the system log, the error shown immediately after mark_deleted() is "Could not find link name of relation ' ' ". I know that it is thrown during and not after the execution of save() because the save() function returns an id of the saved record, but using $GLOBALS['log']->fatal($tBillingMilestone->save()) does not output an id. When this happens, Error 500 is thrown in the browser. Running "Rebuild Relationships" does not help. This function is enclosed in a try-catch clause, which does not catch any exceptions. As I mentioned above, this never happens in the Sugar instance on my local machine.
What are the possible reasons why this error would be thrown?

  • Hi Yury Voloshin,

    Have you written any before_save() logic hook in your BillingMilestone module?

  • Hi Maryam Aslam,

    Yes, I do have a before_save logic hook in BillingMilestone. Great catch! It is the only logic hook in BillingMilestone. It looks like this:

    class DeleteIfUnlinked {

        public function checkIfUnlinked($Bean, $Event, $Arguments) {
            if(count($Bean->billingmilestones_revenuelineitems->getBeans()) === 0){

    billingmilestones_revenuelineitemsis a one-to-many relationship between RevenueLineItems and BillingMilestones. It deletes BillingMilestones that are not associated with a RevenueLineItems. My first thought was that the error is thrown by the checkIfUnlinked function because this function is executed on a bean that has been marked as deleted, which could've caused a problem with loading the relationship. In order to confirm this, I added log statements like this:

    public function checkIfUnlinked($Bean, $Event, $Arguments) {
            $GLOBALS['log']->fatal("in checkIfUnlinked");
            if ($Bean->load_relationship('tcx_billingmilestones_revenuelineitems')) {
                if(count($Bean->tcx_billingmilestones_revenuelineitems->getBeans()) === 0){
                    $GLOBALS['log']->fatal("marked deleted bean with id: " . $Bean->id . "and name " . $Bean->name);
            } else {
                $GLOBALS['log']->fatal("could not load tcx_billingmilestones_revenuelineitems");

    On updating an opportunity, the same error 500 was thrown, but none of the log statements in checkIfUnlinked were displayed in the system log. This implies that the error was thrown before checkIfUnlinked was run. Is there anything else you can think of that might've caused it?

  • Hi Yury Voloshin,

    During the implementations of logic hooks, these behaviors are very obvious if we don't deal it properly as I mentioned here: Why call bean->save() in before_save logic hook? 

    In your case, because I can't debug it but I think the following statements are creating the issue.
    1) Try to remove $BillingMilestone->mark_deleted($BillingMilestone->id); because ultimately it will call in before_save logic hook.

    2) I don't think so that we can call if ($Bean->load_relationship('tcx_billingmilestones_revenuelineitems')) condition in the before_save logic hook because currently bean is not created then how it can load the relationship with the other modules.   

    3) I think you should need to check the $arguments in checkIfUnlinked function in which related_module will have the value Opportunity when it will call by Opportunity and on the basis of this we can isolate it from the before_save logic which is normally used for the record creation. All this is happening because delations, creation and many other operations are handling in the same logic hook. 

    Try all of these, hopefully, it will work! 

  • Thank you Maryam Aslam! I finally fixed it. It was actually a really embarrassing mistake that I found by accessing the PHP log in the  Cloud Insights section. I forgot to add the file with checkIfUnlinked() to the module loader package. While my local instance had this function as shown above, in the online instance the mark_deleted statement had no arguments:


    This threw a PHP error. After I corrected it, everything worked as expected. Thank you again for your help! If nothing else, I now have a better understanding of logic hooks.