Audit events UI shows "(removed)" next to system authors like "(System)"
Everyone can contribute. Help move this issue forward while earning points, leveling up and collecting rewards.
Summary
The audit events table appends "(removed)" to the author name whenever the author has no profile URL. System-generated events use Gitlab::Audit::UnauthenticatedAuthor (author_id -1) with a display name like (System), which never has a profile URL, so every system-authored event renders as:
(System) (removed)
Nothing was removed. The author was never a user, so the suffix is misleading. It reads as if the acting user was deleted, which matters on a page whose whole purpose is forensic review. Severity is low (cosmetic, UI only), but it affects every system-authored event type, and there are 10+ emitters using this author pattern (member management, container registry cleanup, webhook admin destroy, compliance controls timeout, Duo stuck session cleanup, and others).
The stored event and all machine-readable surfaces are correct: REST API, GraphQL, CSV export and streamed payloads all carry "author_name": "(System)" with no suffix. The text is added only at render time in the frontend.
Steps to reproduce
- Open the audit events page (Secure > Audit events) of a project or group that has at least one system-authored event, for example
duo_session_failedemitted by the stuck session cleanup cron, or any event created withGitlab::Audit::UnauthenticatedAuthor. - Look at the Author column.
What is the current bug behavior?
The author cell shows (System) (removed). The same happens for other authors without a profile URL, such as An unauthenticated user (removed) and deploy token authors.
What is the expected correct behavior?
(System) with no suffix. The "(removed)" hint should only appear for authors that used to be real users and were deleted (Gitlab::Audit::DeletedAuthor).
Relevant logs and/or screenshots
Example event from the API (note the clean author_name):
{
"author_id": -1,
"event_name": "duo_session_failed",
"details": {
"author_name": "(System)",
"author_class": "Gitlab::Audit::UnauthenticatedAuthor",
"custom_message": "Duo session failed: stuck session cleaned up after timeout"
}
}This bug happens on GitLab.com.
Possible fixes
The suffix comes from url_table_cell.vue, which renders {{ name }} (removed) for any author without a URL. The URL is produced by AuditEventPresenter#author_url, which returns author.full_path, and NullAuthor#full_path is nil for all subclasses. So the component conflates "no profile to link to" with "user was removed".
Proposal: distinguish the two cases instead of inferring from the missing URL. System authors have well-known negative ids (-1 unauthenticated/system, -2 deploy token, -3 deploy key, -4 orbit indexer), while deleted users are represented by Gitlab::Audit::DeletedAuthor. The presenter (or the serialized row data) can expose an explicit flag, and url_table_cell.vue renders the "(removed)" hint only when that flag is set. Frontend and presenter change only, no backend or data change needed.
Prior art: #386966 (closed) introduced the (System) display name for automated events but the suffix survived because it lives in the frontend cell. #288822 is an older report of "(removed)" showing incorrectly.
