cond takes clauses in pairs, specifically test/expr pairs. That means cond should always have an even number of forms inside it, but yours does not. Your (if ...) form is sitting in the position of a test without a subsequent expr. If we abbreviate things to see the structure, it looks like this:
(cond
;; test ;; expr
(>= ...) circles
(if ...) !!!missing!!!
:else (recur ...))
One way to fix that is to pull out the test from your if but drop the if, like below. (Note: I rearranged your existing logic without testing it, so not sure if this will actually work, but the structure is correct. Also I put the test/expr pairs on separate lines and indented the exprs so they stand out.)
(cond
;; test
;; expr
(>= n total-circles)
circles
(does-circle-have-a-collision circles circle)
(recur n (create-circle) circles)
:else
(recur (inc n) (create-circle) (conj circles circle)))
In the above, calling recur from any expr clause is okay.
You're keeping track of bindings in your loop/recur that you probably don't need. For example, you don't need to track n when you can just check the count of your circles collection. Let's assume you have a function
(defn add-if-no-overlap [coll c] ...)
that returns coll with c added if it doesn't overlap with any circle already in coll, otherwise it returns coll. Then you could generate your 500 non-overlapping circles like so:
(defn generate-circles [total]
(loop [circles ()]
(if (< (count circles) total)
(recur (add-if-no-overlap circles (create-circle)))
circles)))
(generate-circles 500)