7

I am running my query using the Rest API, but I have reproduced the issue in Workbench as well. The below query works for Account, Opportunity, and Contact, but fails for Task:

SELECT UserRecordAccess.MaxAccessLevel FROM Task

The above query gives an error.

Why? Workarounds?

  • 1
    There is no field named UserRecordAccess in Task. Refer developer.salesforce.com/docs/atlas.en-us.api.meta/api/… – Vigneshwaran G May 6 '16 at 20:03
  • 2
    Yes, I am well aware. Do you know about UserRecordAccess ? Same query works agaunst Account, Opportunities, Contacts, etc – user31321 May 6 '16 at 20:09
  • UserRecordAccess is another table Vigneshshwaran - so the commenter's question stands as valid. – MJB May 6 '16 at 20:15
  • Again NOTE the SAME QUERY in WORKBENCH and elsewhere works perfectly in Account, Opportunity, Contact, and Lead. – MJB May 6 '16 at 21:59
  • @MJB Any mention of those was actually absent from OP. – Adrian Larson May 6 '16 at 22:02
4

Why?

The reason why is that activities are expensive to calculating sharing for. While this isn't called out in any manual I could find, I'm certain that's the reason. If you haven't noticed, UserRecordAccess is limited to just a handful of records at a time (you need to specify a user Id and a list of record Ids).

Using the "parent-style" relationship would cause the query to consume tons of resources and slow down the query significantly. They simply don't want you to do this.

In fact, activities in general usually dominate an average org's storage usage, and further, that's why you'll notice that queries against activities must be more selective than (almost) any other type of object (at least for non-admins), are regularly "archived", and have more restrictive data limitations, such as the number and type of fields you can store in activities.

Interestingly enough, they aren't even listed on the SOQL and SOSL Limits page, even though they're some of the most restricted objects in salesforce (but not as restricted as, say, UserRecordAccess itself).

Workarounds?

Query UserRecordAccess directly. This means you'll need to use at least two queries to get a list of tasks or events and the associated UserRecordAccess data (per user per 200 activities per type). There's no two ways about it.

| improve this answer | |
2

The UserRecordAcceess table is more of a "child" object than a parent (more on that later). I think your query should actually be:

SELECT RecordId, MaxAccessLevel FROM UserRecordAccess WHERE ...

Without any WHERE clause it throws:

Where clause must contain UserId = [single ID]


First I tried:

WHERE Record.Type = 'Task'

but it doesn't work. Apparently it's not a true relationship.

Didn't understand relationship 'Record' in field path.


How about the the following?

WHERE RecordId LIKE '00T%'

Nope.

Can filter on only UserId = [single ID], either RecordId = [single ID] or RecordId IN [list of IDs], and Has*Access = true

Hmm, a bit arcane, but it seems to imply that you can only query for access one user at a time. So it seems you may need one request for every User you want to check. For instance I can figure out all records I can access with the following Execute Anonymous script:

Set<Id> taskIds = new Map<Id, Task>([SELECT Id FROM Task LIMIT 10000]).keySet();
system.debug([
    SELECT RecordId, MaxAccessLevel FROM UserRecordAccess
    WHERE UserId = :UserInfo.getUserId()
    AND RecordId IN :taskIds
]);

The following fails with the same error message, implying that you indeed cannot request access levels for multiple users per request.

system.debug([
    SELECT RecordId, MaxAccessLevel FROM UserRecordAccess
    WHERE UserId IN :(UserInfo.getUserId())
    AND RecordId IN :()
]);
| improve this answer | |
  • All I really want to do (sorry in logged in context now) is include the MaxAccessLevel in the different SELECT queries. – MJB May 6 '16 at 21:58
  • Why does it work fine for Account, Contact, Opportunity, Lead, and fail for Task, User, and OpportunityContactRole – MJB May 6 '16 at 21:58
  • @MJB Seems like a bug. What I found at least outlines a very rudimentary workaround... you could build a custom REST service using this strategy, but you'd only be able to get at most 100 users' worth of data. – Adrian Larson May 6 '16 at 22:22

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.