   (fn delete []
     (go
       (let [msg (if verbose
-                  (str "deleting S3 object(s) '" (s/join keys "', '") "'")
+                  (str "deleting S3 object(s) '" (s/join "', '" keys) "'")
                   (str "deleting " (count keys) " S3 object(s)"))]
         (log-action (not should-delete) whatif verbose "Skipped " msg ". Use the --delete option.")
         (log-action should-delete whatif verbose "Started " msg ".")
-
-        (log-action (and should-delete verbose) whatif verbose "Finished " msg ".")
-        [nil true]))))
+        (let [[err _] (if (or whatif (not should-delete))
+                        [nil true]
+                        (<! (delete-s3-objects s3 keys)))]
+          (if err
+            (do
+              (log-action true whatif verbose "Failed while " msg ". " err)
+              [err nil])
+            (do
+              (log-action (and should-delete verbose) whatif verbose "Finished " msg ".")
+              [nil true])))))))
 
 (defn make-copy-file-action [s3 [relpath filepath] whatif verbose]
   (fn copy []

    (go
      (let [msg (str "updating '" relpath "' to S3")]
        (log-action verbose whatif verbose "Comparing local '" relpath "' with remote.")
        (log-action true whatif verbose "Started " msg ".")
        (log-action verbose whatif verbose "Finished " msg ".")
        [nil true]))))

(defn bucketsync
  {:summary "Synchronize a remote Amazon S3 bucket with a local asset directory."

      (cb (str "Could not resolve content-type for '" key "'.") nil))
    ch))

(defn delete-s3-objects [s3 keys]
  (let [params (clj->js {:Delete
                         {:Objects (->> keys
                                        (map (fn [key] {:Key key}))
                                        (vec))}})
        ch (chan)
        cb (fn [err data] (put! ch [err data]))]
    (.deleteObjects s3 params cb)
    ch))

(defn read-local-file [path]
  (let [ch (chan)
        cb (fn [err data] (put! ch [err data]))]
