This also holds for assertz/1 and asserta/1. There reason is very simple. Only dynamic or unknown predicates can be used with database predicates assertz/1, asserta/1 and retract/1. This is the ISO core standard separation of known predicates into dynamic and static.
But then there are some differences among Prolog systems. According to ISO core standard clause/2 is also only allowed for unknown and dynamic predicates, but SWI-Prolog allows it for static predicates as well. Which can be quite useful sometimes.
Similarly there are differences in retract/1 and retractall/1 if the predicate is unknown. For example that SWI-Prolog creates a new dynamic entry during retractall/1, is not required by the standard. The usual bootstrapping(*) would be:
retract((Head :- _)),
And according to ISO core standard retract/1 can fail silently if the predicate is unknown. This is seen here, where SWI-Prolog is compliant:
Welcome to SWI-Prolog (threaded, 64 bits, version 8.1.22)
ERROR: Unknown procedure: foo/1 (DWIM could not correct goal)
(*) DRAFT TECHNICAL CORRIGENDUM 2