Having a similar requirement I stumbled upon the same problem. There is a hidden AccountId field, which allows you to reference related Account fields. This field is filled for you by Salesforce, but only after saving it to the database (as the WhatId field is polymorphic Salesforce doesn't know yet where to look for the related Account).
If you would run a
before insert and an
after insert trigger on Task or Event only logging the values in
Trigger.new, you will notice that there are two fields that have changed in between: the ActivityDate and the AccountId. Apparently SF does some processing itself in between to populate these.
The validation rules are evaluated before this happens so this AccountId field is empty in your validation rule. See also the order of execution:
- Executes all before triggers.
- Runs most system validation steps again, such as verifying that all required fields have a non-null value, and runs any user-defined
validation rules. The only system validation that Salesforce doesn't
run a second time (when the request comes from a standard UI edit
page) is the enforcement of layout-specific rules.
- Saves the record to the database, but doesn't commit yet.
- Executes all after triggers.
- Executes workflow rules.
- If there are workflow field updates, updates the record again.
- If the record was updated with workflow field updates, fires before update triggers and after update triggers one more time (and
only one more time), in addition to standard validations. Custom
validation rules, duplicate rules, and escalation rules are not run
- Executes processes and flows launched via processes and flow trigger workflow actions. When a process or flow executes a DML
operation, the affected record goes through the save procedure.
- Commits all DML operations to the database.
I suspect that your AccountId is populated before step 6 or maybe 7. This means that in a workflow field update for example the Account fields are available for referencing. However, as noted in 12, these won't run validation rules again.
Your remaining no-code option is to create a checkbox field on Activity called Account is inactive, create a process that checks the Account's Active field, and if not, ticks your Account is inactive checkbox. On Task you create a validation rule that evaluates just this checkbox. (Although by this you could also directly check the original Account's Active field as it should be available by this point - I haven't tried that out though).
The major downside of this approach is the ugly error message you get:
We can't save this record because the “Account inactive validation” process failed. Give your Salesforce admin these details.
This error occurred when the flow tried to update records:
FIELD_CUSTOM_VALIDATION_EXCEPTION: This account is marked as inactive.. You can look up ExceptionCode values in the SOAP API Developer Guide. Error ID: 238050955-206580 (-58786743)
...and of course the accompanying email you will get delivered nicely in your inbox every time someone hits your validation rule.