I am trying to load all tasks of a contact via SOQL query:
SELECT Id, Subject FROM Task WHERE WhoId = 'contactId'
This query returns only partial list of Tasks. I.e. in UI I see tasks directly attached to this Contact which are not being returned as part of the result for this query.
I googled a bit and found out that I might need to query an ActivityHistory sobject and yes querying it returns me "missing" tasks as well:
SELECT (SELECT Id, Subject FROM ActivityHistories) FROM Contact WHERE Id ='contactId'
So, my question is that an expected behavior? I.e. there is no way to load all the Tasks using 1 query and I have to load both Tasks and AcitivityHistories?
Also, interestingly, I couldn't reproduce this situation in a developer account: I've registered a Task with subject 'other' that took place in the past and in UI it is displayed in Activity History section, but I receive it is a part of normal Task loading query. So, i am not really sure why the Task in originally described situation is not returned with simple Task query (i.e. only in ActivityHistories query)
Best Answer
Salesforce archives older activities. From the docs:
When these conditions are meet* the Task no longer appears in SOQL queries against the Task sObject. Instead you need to use the ActivityHistory "view" in a relationship query from the parent sObject.
* It appears the archival process isn't immediate. If you set a Tasks Due Date to be more than one year old it will still appear against the Task sObject for a period of time. Most likely Salesforce has a scheduled job to process the archival.
Useful notes from the docs:
So ActivityHistory is more like a view that collectively returns both Tasks and Events and archived records.
A couple of other thoughts as to why you might see a record in ActivityHistory but not in Task.
As per the discussion, we have confirmed that you are dealing with a task