Você quer algo assim:
CREATE OR REPLACE TRIGGER TRIGGER_D
BEFORE
INSERT OR UPDATE ON CONTRACTS
FOR EACH ROW
DECLARE
BEGIN
UPDATE CONTRACTS
SET ENDDATE = :NEW.STARTDATE - INTERVAL '1' DAY
WHERE CLIENTID = :NEW.CLIENTID
AND ENDDATE > :NEW.STARTDATE
AND STARTDATE < :NEW.STARTDATE;
END;
No entanto, ele está atualizando a tabela que o gatilho está monitorando e parece provável que o gatilho cause atualizações que invocarão o gatilho novamente e obterão um erro de tabela mutante.
Talvez seja melhor agrupar sua lógica de negócios em um procedimento armazenado onde ela possa realizar a atualização nas linhas anteriores e, em seguida, fazer a inserção/atualização. Então, em vez de executar instruções DML diretamente na tabela, invoque o procedimento armazenado.