                         delete_missing    : assignment.get('delete_missing')
                         timeout           : assignment.get('timeout')
                         cb                : (err) =>
-                            if err
-                                cb(err)
-                            else
-                                where = {table:'assignments', assignment_id:assignment_id}
-                                assignment = syncdb.select_one(where:where)
-                                last_assignment = assignment.last_assignment ? {}
-                                last_assignment[student_id] = {time: misc.mswalltime()}
-                                @_update(set:{last_assignment:last_assignment}, where:where)
-                                cb?()
+                            where = {table:'assignments', assignment_id:assignment.get('assignment_id')}
+                            last_assignment = syncdb.select_one(where:where).last_assignment ? {}
+                            last_assignment[student.get('student_id')] = {time: misc.mswalltime(), error:err}
+                            @_update(set:{last_assignment:last_assignment}, where:where)
+                            cb(err)
             ], (err) =>
                 if err
-                    return error("failed to send assignment -- #{err}")
+                    return error("failed to send assignment to #{student_name} -- #{err}")
+                @set_activity(id:id)
                 cb?()
             )
 
         # Copy the given assignment to all non-deleted students, doing 10 copies in parallel at once.
-        copy_assignment_to_all_students: (assignment_id, cb) =>
-            error = (err) => err="copy to student: #{err}"; @set_error(err); cb?(err)
+        copy_assignment_to_all_students: (assignment, cb) =>
+            id = @set_activity(desc:"Copying assignments to all students")
+            error = (err) =>
+                @set_activity(id:id)
+                err="copy to student: #{err}"; @set_error(err); cb?(err)
             if not @_store_is_initialized()
                 return error("store not yet initialized")
-            if not assignment = store.get_assignment(assignment_id)
+            if not assignment = store.get_assignment(assignment)
                 return error("no assignment")
             errors = ''
-            f = (student_id, cb) =>
-                @copy_assignment_to_student assignment_id, student_id, (err) =>
+            f = (student, cb) =>
+                @copy_assignment_to_student assignment, student, (err) =>
                     if err
                         errors += "\n #{err}"
                     cb()

                    if x.table == 'settings'
                        misc.merge(t.settings, misc.copy_without(x, 'table'))
                    else if x.table == 'students'
                        t.students[x.student_id] = misc.copy_without(x, ['student_id', 'table'])
                    else if x.table == 'assignments'
                        t.assignments[x.assignment_id] = misc.copy_without(x, ['assignment_id', 'table'])
                for k, v of t
                    t[k] = immutable.fromJS(v)
                actions._set_to(t)

            return misc.cmp(a.path.toLowerCase(), b.path.toLowerCase())
        for x in v
            <Assignment key={x.assignment_id} assignment={@props.assignments.get(x.assignment_id)}
                    project_id={@props.project_id}  flux={@props.flux}
                    students={@props.students} user_map={@props.user_map}
                    name={@props.name}
                    />

    render :->
        <Panel header={@render_header()}>
