• Glenn Weinstein
  • NEWBIE
  • 30 Points
  • Member since 2006
  • CIO
  • Appirio


  • Chatter
    Feed
  • 0
    Best Answers
  • 38
    Likes Received
  • 0
    Likes Given
  • 3
    Questions
  • 15
    Replies

Ran into an interesting Salesforce-to-Salesforce (S2S) problem I thought I'd share - it appears the S2S Connection Owner cannot insert share records via Apex trigger.

 

We have S2S configured in our org to receive Case records from another org.  Separately, we have a Case trigger to insert a custom "Performance Rating" object record anytime a Case is closed (to rate the owner).  This, in turn, fires a Performance Rating trigger to share the newly inserted record with the Case owner.

 

It all works fine normally.  But when a Case is closed via S2S connection, the Performance Rating trigger is failing with an INSUFFICIENT_ACCESS_ON_CROSS_REFERENCE_ENTITY exception.  Apparently, the S2S Connection User isn't being allowed to insert  the new Performance_Rating__Share record.  The error occurs on the last line in the trigger below:

 

Trigger shareWithRelatedRecordOwner on Performance_Rating__c (after insert, after update) {
  List<Performance_Rating__Share> prShareList = new List<Performance_Rating__Share>();
  for (Performance_Rating__c pr : Trigger.new) {
    if(pr.Related_Record_Owner__c != null) {
      Performance_Rating__Share prShare = new Performance_Rating__Share();
      prShare.ParentId = pr.Id;
      prShare.UserOrGroupId = pr.Related_Record_Owner__c;
      prShare.AccessLevel = 'read';
      prShare.RowCause = Schema.Performance_Rating__Share.RowCause.Related_Record_Owner__c;
      prShareList.add(prShare);
    }
  }
  insert prShareList;
}

 Note that "with sharing" isn't coming into play here, so I believe the trigger should be running in system (aka "god") mode, and it really shouldn't matter who the running user is.

 

My theory is that we're hitting some odd bug related to the S2S Connection User.  In my view, this trigger should always work - it shouldn't fail just because it's being invoked as the result of an update made to a record via S2S.

 

Our quick & dirty workaround was to simply put a try/catch around the insert, and eat the error.  But wow, that is an unsatisfying resolution (and it results in the new record NOT being shared with the original Case owner, per the intent of the trigger).

 

I'd welcome any alternate theories.

 

 

 

 

Posting this in order to help others who, months from now, might Google "OP_WITH_INVALID_USER_TYPE_EXCEPTION" and find this explanation.

 

We wrote an Apex trigger on the User object, to insert a custom object record anytime a user updates their Chatter status.  This was done to fulfill a client's requirement to audit all Chatter activity.

 

The trigger worked fine, until one day the client signed up some Chatter Free users.  When such a user tried to update their status, they got a pop-up with an OP_WITH_INVALID_USER_TYPE_EXCEPTION error.

 

We scratched our collective heads for awhile.  After all, Apex triggers run in "system mode," right?  That is supposed to mean that "object and field-level permissions of the current user are ignored."  And yet this trigger seemed like it was running in "user mode," enforcing restrictions based on who the current user was.

 

The root cause turned out to be that a Chatter Free user cannot be the owner of a custom object record, and SFDC by default sets the current user as a new record's first owner.  We discovered this when we realized, via experiment, that Apex triggers fired as the result of actions by Chatter Free users could definitely update an existing record, but were having problems creating records.

 

So the simple solution was to explicitly set the owner of the new record to some fully-licensed user prior to inserting it.

I'm posting this problem & solution to help others who may encounter a similar issue.

In s-controls, Salesforce.com performs substitutions on merge fields (e.g. {!Account_Name}) before sending the Javascript to the client's browser for processing.  This means merge fields can't be used in the same way as normal Javascript variables.  This doesn't usually present a problem, but special caution is required when working with a numeric merge field (as opposed to a string merge field).  If the field can be null, you could cause a sneaky syntax error in your Javascript.  For example, consider the following line of Javascript in an s-control:

if ({!Contact_Age} > 65) { doSomething(); }

This looks innocent enough, but if Contact_Age is null, the line will be passed to the browser as:

if ( > 65) { doSomething(); }

Most browsers (certainly Firefox and IE) will throw a syntax error and refuse to process the Javascript, even if that specific line of code is never executed - Javascript interpreters tend to scan for syntax errors prior to starting runtime interpretation.  So - how can we work around this?  The easiest way is to ensure any inline use of a numeric merge field is wrapped in a string, then converted back to a number as follows:

if (Number("{!Contact_Age}") > 65) { doSomething(); }

The Number() function will evaluate a blank string ("") as the number 0, so be sure that your logic works correctly by treating a numeric value as 0 when it's null.  If this causes a logic problem, you can always test for null first, with a line of code like this:

if "{!Contact_Age}" == "" { assumeAgeIsNull() };

I hope this helps someone!

Glenn Weinstein
Principal
Appirio, Inc.



Ran into an interesting Salesforce-to-Salesforce (S2S) problem I thought I'd share - it appears the S2S Connection Owner cannot insert share records via Apex trigger.

 

We have S2S configured in our org to receive Case records from another org.  Separately, we have a Case trigger to insert a custom "Performance Rating" object record anytime a Case is closed (to rate the owner).  This, in turn, fires a Performance Rating trigger to share the newly inserted record with the Case owner.

 

It all works fine normally.  But when a Case is closed via S2S connection, the Performance Rating trigger is failing with an INSUFFICIENT_ACCESS_ON_CROSS_REFERENCE_ENTITY exception.  Apparently, the S2S Connection User isn't being allowed to insert  the new Performance_Rating__Share record.  The error occurs on the last line in the trigger below:

 

Trigger shareWithRelatedRecordOwner on Performance_Rating__c (after insert, after update) {
  List<Performance_Rating__Share> prShareList = new List<Performance_Rating__Share>();
  for (Performance_Rating__c pr : Trigger.new) {
    if(pr.Related_Record_Owner__c != null) {
      Performance_Rating__Share prShare = new Performance_Rating__Share();
      prShare.ParentId = pr.Id;
      prShare.UserOrGroupId = pr.Related_Record_Owner__c;
      prShare.AccessLevel = 'read';
      prShare.RowCause = Schema.Performance_Rating__Share.RowCause.Related_Record_Owner__c;
      prShareList.add(prShare);
    }
  }
  insert prShareList;
}

 Note that "with sharing" isn't coming into play here, so I believe the trigger should be running in system (aka "god") mode, and it really shouldn't matter who the running user is.

 

My theory is that we're hitting some odd bug related to the S2S Connection User.  In my view, this trigger should always work - it shouldn't fail just because it's being invoked as the result of an update made to a record via S2S.

 

Our quick & dirty workaround was to simply put a try/catch around the insert, and eat the error.  But wow, that is an unsatisfying resolution (and it results in the new record NOT being shared with the original Case owner, per the intent of the trigger).

 

I'd welcome any alternate theories.

 

 

 

 

Posting this in order to help others who, months from now, might Google "OP_WITH_INVALID_USER_TYPE_EXCEPTION" and find this explanation.

 

We wrote an Apex trigger on the User object, to insert a custom object record anytime a user updates their Chatter status.  This was done to fulfill a client's requirement to audit all Chatter activity.

 

The trigger worked fine, until one day the client signed up some Chatter Free users.  When such a user tried to update their status, they got a pop-up with an OP_WITH_INVALID_USER_TYPE_EXCEPTION error.

 

We scratched our collective heads for awhile.  After all, Apex triggers run in "system mode," right?  That is supposed to mean that "object and field-level permissions of the current user are ignored."  And yet this trigger seemed like it was running in "user mode," enforcing restrictions based on who the current user was.

 

The root cause turned out to be that a Chatter Free user cannot be the owner of a custom object record, and SFDC by default sets the current user as a new record's first owner.  We discovered this when we realized, via experiment, that Apex triggers fired as the result of actions by Chatter Free users could definitely update an existing record, but were having problems creating records.

 

So the simple solution was to explicitly set the owner of the new record to some fully-licensed user prior to inserting it.

I'm posting this problem & solution to help others who may encounter a similar issue.

In s-controls, Salesforce.com performs substitutions on merge fields (e.g. {!Account_Name}) before sending the Javascript to the client's browser for processing.  This means merge fields can't be used in the same way as normal Javascript variables.  This doesn't usually present a problem, but special caution is required when working with a numeric merge field (as opposed to a string merge field).  If the field can be null, you could cause a sneaky syntax error in your Javascript.  For example, consider the following line of Javascript in an s-control:

if ({!Contact_Age} > 65) { doSomething(); }

This looks innocent enough, but if Contact_Age is null, the line will be passed to the browser as:

if ( > 65) { doSomething(); }

Most browsers (certainly Firefox and IE) will throw a syntax error and refuse to process the Javascript, even if that specific line of code is never executed - Javascript interpreters tend to scan for syntax errors prior to starting runtime interpretation.  So - how can we work around this?  The easiest way is to ensure any inline use of a numeric merge field is wrapped in a string, then converted back to a number as follows:

if (Number("{!Contact_Age}") > 65) { doSomething(); }

The Number() function will evaluate a blank string ("") as the number 0, so be sure that your logic works correctly by treating a numeric value as 0 when it's null.  If this causes a logic problem, you can always test for null first, with a line of code like this:

if "{!Contact_Age}" == "" { assumeAgeIsNull() };

I hope this helps someone!

Glenn Weinstein
Principal
Appirio, Inc.



Ran into an interesting Salesforce-to-Salesforce (S2S) problem I thought I'd share - it appears the S2S Connection Owner cannot insert share records via Apex trigger.

 

We have S2S configured in our org to receive Case records from another org.  Separately, we have a Case trigger to insert a custom "Performance Rating" object record anytime a Case is closed (to rate the owner).  This, in turn, fires a Performance Rating trigger to share the newly inserted record with the Case owner.

 

It all works fine normally.  But when a Case is closed via S2S connection, the Performance Rating trigger is failing with an INSUFFICIENT_ACCESS_ON_CROSS_REFERENCE_ENTITY exception.  Apparently, the S2S Connection User isn't being allowed to insert  the new Performance_Rating__Share record.  The error occurs on the last line in the trigger below:

 

Trigger shareWithRelatedRecordOwner on Performance_Rating__c (after insert, after update) {
  List<Performance_Rating__Share> prShareList = new List<Performance_Rating__Share>();
  for (Performance_Rating__c pr : Trigger.new) {
    if(pr.Related_Record_Owner__c != null) {
      Performance_Rating__Share prShare = new Performance_Rating__Share();
      prShare.ParentId = pr.Id;
      prShare.UserOrGroupId = pr.Related_Record_Owner__c;
      prShare.AccessLevel = 'read';
      prShare.RowCause = Schema.Performance_Rating__Share.RowCause.Related_Record_Owner__c;
      prShareList.add(prShare);
    }
  }
  insert prShareList;
}

 Note that "with sharing" isn't coming into play here, so I believe the trigger should be running in system (aka "god") mode, and it really shouldn't matter who the running user is.

 

My theory is that we're hitting some odd bug related to the S2S Connection User.  In my view, this trigger should always work - it shouldn't fail just because it's being invoked as the result of an update made to a record via S2S.

 

Our quick & dirty workaround was to simply put a try/catch around the insert, and eat the error.  But wow, that is an unsatisfying resolution (and it results in the new record NOT being shared with the original Case owner, per the intent of the trigger).

 

I'd welcome any alternate theories.

 

 

 

 

I am getting java.lang.reflect.InvocationTargetException when I am trying to edit and save an existing Test Class. The same test class, I am able to edit and save in another sandbox of the same Production instance. Any help is appreciated.

  • November 07, 2013
  • Like
  • 0

Working on a bit of code for a salesforce hosted site that will create a campaign member. Getting this error. I have seen something like this before, when you pass a bad ID, but it usually tells you which ID is bad, here it just says null. This code works perfectly in sandbox, but fails in production, so it seems like it must just be some security setting is off, but I have no idea what setting it could be.

 

We do have the private data model, with sharing rules set up for contacts (but of course sharing rules don't apply to the sites guest user). 

 

The full error is 

Error creating campaign member. Insert failed. First exception on row 0; first error: INSUFFICIENT_ACCESS_ON_CROSS_REFERENCE_ENTITY, insufficient access rights on cross-reference id: [] null System.DmlException Error during campaign member creation. Contact: 0034000000kJdQQ Campaign: 70140000000N01iAAC null scheduler.customException 

 

So you can see the campaign and contact are being passed in. Both of those are valid IDs in the org. So I don't think that is the issue (I know I've seen that before when passing in a bad hard coded ID).

 

What security settings could I look at to try and fix this? I feel like I've looked at all the applicable public access settings for the user (contact, campaign member, and campaign settings are maxed out).

 

Any help is appreciated. Thanks!

Hey all,

 

Is there a way to display previous change data for fields on a Visualforce e-mail template, similar to Apex's trigger.old?

 

Eg "The Opportunity name has changed.  Old value: XYZ.  New Value: ABC".

 

I know I can 100% do this by coding the e-mail template in Apex-- but I really would prefer to write these sorts of e-mails with Visualforce if at all possible.

 

If anyone knows anything, it would be MUCH appreciated.

 

Thanks!

 

  • August 10, 2010
  • Like
  • 0

I am trying to create a trigger that sends an Email Alert (or just an email though Apex code) to the original Idea poster whenever a comment is left for their idea. In looking through the Apex documentation, I noticed it says you can only define triggers for top-level standard objects, but not for standard child objects. When I try to do something like this:

 

 

trigger commentEmail on IdeaComment (after insert) {
// send email code here
}

 

I get "Error: Compile Error: SObject type does not allow triggers: IdeaComment at line 1 column 25". Can anyone point in the right direction to get around this? 

 

 

 

Is there a way to get the "id" of a picklist value through the API?  We are using picklist values in an external system and when a picklist value is updated, would like to "push" this updated value to the external system via the id.

 

Looking at the edit page, it seems it may be possible to get at the id, but I do not see this available through the API.  Is there a way to get this id value?

 

Examples through the edit screen:
picklist_masteredit.jsp?id=01J400000088LJZ
picklist_masteredit.jsp?id=01J400000088LJa

 

Thanks!

I am trying to implement my own email-to-case class and I have the following code, which is working in my sandbox, to create an EmailMessage on a case using email services:
 
EmailMessage[] newEmail = new EmailMessage[0];
 
newEmail.add(new EmailMessage(FromAddress = email.fromAddress,
FromName = email.fromName,
ToAddress = email.toAddresses[0],
Subject = email.subject,
TextBody = email.plainTextBody,
HtmlBody = email.htmlBody,
ParentId = newCase[0].Id, 
ActivityId = newTask[0].Id));   // (newCase and newTask are the newly created case and task from earlier code)
 
insert newEmail;
 
I have several questions.  Is it possible to set the email message status to "New"?  If I attempt to add "Status = 'New'" in the .add() method I get an error: Message: Insert failed. First exception on row 0; first error: INVALID_OR_NULL_FOR_RESTRICTED_PICKLIST, Status: bad value for restricted picklist field: New: [Status] null.  If I don't attempt to set the status, it defaults to "Sent".
 
Also, does anyone have any sample code to share that adds headers and attachments from an inbound email to an Email Message object?  I'm struggling with that one.
 
Another minor issue that is bugging me is that in the Email Section of the Case page in my sandbox, the column labelled "Email Address" shows the 'to address' and my production version using the the standard SFDC email to case application will have the 'from address' (contact's address) displayed.  Does anyone know what field in the Email Message object this data comes from?
 
Thanks for the help!
I am trying to do a relationship query for EmailMessages associated with a Case.  However, something seems to be "special" about this relationship.

Normally, I can retrieve related lists like this:

SELECT id, (SELECT CommentBody FROM Case.CaseComments) FROM Case WHERE id = '50050000003DZRB'

However, this approach doesn't seem to work with EmailMessages.  I don't see any related list for EmailMessages in the Enterprise WSDL, but surprisingly, a relatinship does show up in the schema browser Apex Toolkit for Eclipse.  However the relationship looks "funny" there - you can't drill into it like you can with the other Case relationships (it has a blue ball next to it instead of a plus sign), so you can't view the relationship name.  For the sake of trying everything, I experimented with some guesses at the relationship name -

(SELECT id FROM Case.EmailMessages)
(SELECT id FROM Case.CaseEmailMessages)
(SELECT id FROM Case.Emails)
(SELECT id FROM Case.CaseEmails)

None of these worked.  But it feels like this should be doable - the EmailMessage object has a "ParentID" field that points back to the Case, so I can always do a separate SOQL query on EmailMessage.  But I'd hoped to use a relationship query here, for various reasons.

Can anyone explain the apparently "special" relationship from Case to EmailMessage?
Can you execute an s-control from an s-control and if so can someone post a small example.  Thanks in advance. 
Recently, I setup email-to-case and I think it is just about configured correctly except for one issue I am having.

When the agent polls the IMAP server to retrieve email messages it appears that they are not being marked as "read". Because of this every time the agent polls the server (every 10 minutes) the same emails keep getting pulled and sent to SF creating duplicate case of the same emails.

Question: how does the agent mark the messages so this does not occur? I thought it had to do with the testProcessing folder but I am not exactly sure how this part is suppose to function.

Any help is greatly appreciated. Thanks much.

Paul