Hello, here's is the trigger code I ended up using: ```sql CREATE TRIGGER cycle_check BEFORE INSERT ON tag_parents FOR EACH ROW BEGIN SELECT RAISE(ABORT, 'Cycle detected') WHERE EXISTS ( WITH RECURSIVE w(parent, last_visited, already_visited, cycle) AS ( SELECT DISTINCT to_tag_id AS parent, from_tag_id AS last_visited, to_tag_id AS already_visited, 0 AS cycle FROM tag_parents UNION ALL SELECT t.to_tag_id AS parent, t.from_tag_id AS last_visited, already_visited || ', ' || t.to_tag_id, already_visited LIKE '%'||t.to_tag_id||"%" FROM tag_parents AS t JOIN w ON w.last_visited = t.to_tag_id WHERE NOT cycle ) SELECT already_visited, cycle FROM w WHERE last_visited = NEW.to_tag_id AND already_visited LIKE '%'||NEW.from_tag_id||'%' ); END; ``` I hope it proves useful (and correct) for anyone with a similar problem. I made a small writeup [here](https://sic.nessuent.xyz/s/18/detecting-cycles-in-tag-parent-child-relationship-in-sqlite3/) with a tiny bit more detail if anyone is interested.