4

Users in a certain profile (in production) cannot see a new Visualforce page (or rather, a component within the Visualforce page) I've added to the Opportunity layout. The error is

Content cannot be displayed: Invalid parameter for function URLFOR

I've monitored some users with increased log levels. For some reason the status is marked as success, and this is what I get:

11:09:28.107 (107494903)|VF_EVALUATE_FORMULA_BEGIN|06612000000Wiyq|#{URLFOR($Action.Contact.View, relations.Contact.ID)}
11:09:28.108 (108425979)|VF_EVALUATE_FORMULA_END
11:09:28.108 (108787037)|VF_EVALUATE_FORMULA_BEGIN|06612000000Wiyq|#{URLFOR($Action.Account.View, group.ID)}
11:09:28.109 (109584313)|VF_EVALUATE_FORMULA_END

There's also another one that includes jQuery in the Visualforce page. I assume that's not the issue because other profiles are just fine. Given that, what's causing the error? Personally, I think the error is misleading and that there's some sort of permissions issue because the exact same Opportunity is viewed correctly by some profiles.


Latest news: One of my admin users was experimenting, and giving the profile create permissions on Contacts and a custom object (both used by the Visualforce component) and then removing those permissions seems to have fixed the issue. This makes me queasy. Please explain.
Code extracts

Relevant Visualforce component snippet:

<apex:pageBlockTable id="grid" value="{!Relationships}" var="relations" width="100%">
    <apex:column headerValue="Contact Name">
        <apex:outputLink target="_top"
                         value="{!URLFOR($Action.Contact.View, relations.Contact.ID)}">
            {!relations.Contact.LastName}, {!relations.Contact.FirstName}
        </apex:outputLink>
    </apex:column>
    <apex:column headerValue="Account Name">
        <apex:repeat value="{!relations.Groups}" var="group">
            <apex:outputLink target="_top"
                             value="{!URLFOR($Action.Account.View, group.ID)}">
                {!group.Name}
            </apex:outputLink>
            {! IF(group != relations.Groups[relations.Groups.Size - 1], ';', '')}
        </apex:repeat>
    </apex:column>
</apex:pageBlockTable>

The controller (more or less):

public ID AccountID {
    get;
    set {
        AccountID = value;
        if (Relationships == null) Load();
    }
}

public List<ContactRelations> Relationships { get; protected set; }

public void Load() {
    // Get data
    Account a = [SELECT ID, Name, ParentID FROM Account WHERE ID = :AccountID];
    ID parentID = a.ParentId == null ? a.ID : a.ParentId;
    List<Account> accounts =
        [SELECT ID, Name, ParentID, RecordType.Name
         FROM Account
         WHERE ID = :parentID
         OR ParentID = :parentID
         ORDER BY Name];

    Relationships = new List<ContactRelations>();
    for (Contact_Relationships__c crc:
         [SELECT
              ID,
              Related_Contact__r.ID,
              Related_Contact__r.Name,
              Related_Contact__r.FirstName,
              Related_Contact__r.LastName,
              Related_Account__r.ID,
              Related_Account__r.Name,
              Related_Account__r.RecordType.Name,
              Relationship_Type__c
          FROM Contact_Relationships__c
          WHERE Related_Account__c IN :accounts]) {
              boolean flag = false;
              for (ContactRelations cr: Relationships) {
                  if (cr.Contact.ID == crc.Related_Contact__c) {
                      cr.Relationships.add(crc);
                      flag = true;
                      break;
                  }
              }
              if (!flag) {
                  ContactRelations cr = new ContactRelations();
                  cr.Contact = crc.Related_Contact__r;
                  cr.Relationships.add(crc);
                  Relationships.add(cr);
              }
    }
    Relationships.sort();
}

And ContactRelations is this class (simplified):

public class ContactRelations {
    public Contact Contact { get; set; }
    public Set<Contact_Relationships__c> Relationships {
        get {
            if (Relationships == null) {
                Relationships = new Set<Contact_Relationships__c>();
            }
            return Relationships;
        }
        set;
    }

    public List<Account> getGroups() {
        Set<Account> subgroups = new Set<Account>();
        Account parent;
        for (Contact_Relationships__c cr: Relationships) {
            if (cr.Related_Account__r.RecordType.Name == 'Group') {
                parent = cr.Related_Account__r;
            }
            else subgroups.add(cr.Related_Account__r);
        }
        List<Account> groups = new List<Account>();
        if (parent != null) groups.add(parent);// List the group first
        List<Account> temp = new List<Account>(subgroups);
        temp.sort();
        groups.addAll(temp);
        return groups;
    }
}
3
  • what is relations.contact.id , group.Id ? is relations a list ? can you post more code on how relations is being formed and what group.id is ?
    – Rao
    Mar 31 '15 at 21:18
  • since you are only using view in the action attribute read permission should be more than enough on the custom object and contacts. Check if you can pull it off with just Read permission and kill the create permission.
    – Rao
    Apr 1 '15 at 21:55
  • Yes, it works with just the Read permission. I updated the Latest News section of the question. The profile always had Read permission, so why is it working after adding and removing the Create permission? That's the mystery. Maybe my user did something else as well, but she couldn't remember doing anything else.
    – ricksmt
    Apr 2 '15 at 16:46
-1

Check if the access of the vf page and controller is given to the profile for which error is coming. In profile, there is options "Enabled Access for classes" and "Enabled Access for visualforce pages"

1
  • 1
    They have explicit access to the Visualforce page, which implicitly includes the controller. They would have received a different error if that were the case.
    – ricksmt
    Mar 31 '15 at 18:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.