throw if cycle detected