       (sequential? id)
       (let [[a v] id]
         (if-not (unique? db-snap a)
-          (throw (js/Error (str "Not a unique attribute: " a v)))
+          (throw (js/Error (str "Not a unique attribute: " a ", with value: " v)))
           (get-in* db-snap [:index a v])))
       id)))
 

   (unlisten-path! db [:listeners :entity id] f))
  ([db id attr f]
   (unlisten-path! db [:listeners :entity-attr id attr] f)))

(defn upsert-attr? [id]
  (and (number? id) (neg? id)))

(defn entity [db-snap id]
  (when-let [id (resolve-id db-snap id)]

   (when-let [{:keys [f message] :as validation} (get-in* db-snap [:schema attr :validate])]
     (or (f val) (throw js/Error (str "Validation failed for " attr ": " message " on " val))))

   (let [many? (many? db-snap attr)
         ;multi-many? (and many? (sequential? val))
         no-op? (if many?
                  (contains? (get* (entity db-snap id) attr) val)
                  ;; some invalid values throw when compared, eg `(map inc (take 2))`
                  (try (= val (get db-snap id attr))
                       (catch js/Error e false)))]
     (cond
       no-op? [db-snap reports]

       ;multi-many? (reduce #(add %1 id attr %2) [db-snap reports] val)

       many? (-> [(update-in db-snap [:data id attr] (fnil conj #{}) val)
                  (conj reports [id attr val nil])]
