Audit event type YML file is not defined for ticket_closed_by_project_bot. returned when a group or project access token is used to close a Service Desk ticket
Summary
When attempting to close a Service Desk ticket using the Issues API, and authenticating with a project or group access token, the user is returned with a 500 error, however the work item closes successfully.
Checking Rails logs, you can see the below logged exception.
Audit event type YML file is not defined for ticket_closed_by_project_bot. Please read https://docs.gitlab.com/ee/development/audit_event_guide/#how-to-instrument-new-audit-events for adding a new audit event
Steps to reproduce
- Create a service desk ticket in a project
- Attempt to close the service desk issue using the API and authenticating with a project or group access token
- Notice the issue closes, but the HTTP response is 500
Example Project
N/A
What is the current bug behavior?
An erroneous 500 response is returned, and no audit event is created for the service desk issue being closed.
What is the expected correct behavior?
A non-500 response should be returned, and an audit event should be created for the closure.
Relevant logs and/or screenshots
Output of checks
This bug happens on GitLab.com
Results of GitLab environment info
<details> <summary>Expand for output related to GitLab environment info</summary>
<pre>
(For installations with omnibus-gitlab package run and paste the output of:
sudo gitlab-rake gitlab:env:info)
(For installations from source run and paste the output of:
sudo -u git -H bundle exec rake gitlab:env:info RAILS_ENV=production)
</pre> </details>
Results of GitLab application Check
<details> <summary>Expand for output related to the GitLab application check</summary> <pre>
(For installations with omnibus-gitlab package run and paste the output of:
sudo gitlab-rake gitlab:check SANITIZE=true)
(For installations from source run and paste the output of:
sudo -u git -H bundle exec rake gitlab:check RAILS_ENV=production SANITIZE=true)
(we will only investigate if the tests are passing)
</pre> </details>
Possible fixes
Patch release information for backports
If the bug fix needs to be backported in a patch release to a version under the maintenance policy, please follow the steps on the patch release runbook for GitLab engineers.
Refer to the internal "Release Information" dashboard for information about the next patch release, including the targeted versions, expected release date, and current status.
High-severity bug remediation
To remediate high-severity issues requiring an internal release for single-tenant SaaS instances, refer to the internal release process for engineers.
Root Cause Analysis
The audit event name is dynamically generated in app/services/issues/close_service.rb (lines 58-60):
if current_user.project_bot?
log_audit_event(issue, current_user, "#{issue.issue_type}_closed_by_project_bot",
"Closed #{issue.issue_type.humanize(capitalize: false)} #{issue.title}")
end
When issue.issue_type returns ticket, the generated audit event name becomes ticket_closed_by_project_bot. However, no corresponding YML definition exists in ee/config/audit_events/types/, causing the error.
This gap exists because the ticket work item type was introduced as part of the Service Desk migration to work items after the original audit events were created in GitLab 16.1 (!121485 (merged)).
Why "project_bot" in the naming
The _by_project_bot suffix is a historical artifact. Both project and group access tokens create users with user_type: project_bot (defined in app/models/concerns/has_user_type.rb). The check current_user.project_bot? returns true for both token types, which is why the audit event naming uses project_bot even when a group access token is used.
Implementation Plan
1. Create audit event type definitions
Add the following files in ee/config/audit_events/types/:
-
ticket_closed_by_project_bot.yml -
ticket_reopened_by_project_bot.yml -
ticket_created_by_project_bot.yml(proactive, for future API support)
Each file should follow the existing pattern. Example for ticket_closed_by_project_bot.yml:
---
name: ticket_closed_by_project_bot
description: A Service Desk ticket is closed using a project access token
introduced_by_issue: https://gitlab.com/gitlab-org/gitlab/-/issues/592448
introduced_by_mr: <MR URL>
feature_category: service_desk
milestone: '<current milestone>'
saved_to_database: true
streamed: true
scope: [Project]
2. Regenerate audit event documentation
-
Run
bundle exec rake gitlab:audit_event_types:compile_docsto updatedoc/user/compliance/audit_event_types.md
3. Add specs
Update existing spec files to include ticket-specific test cases:
-
ee/spec/services/ee/issues/close_service_spec.rb- Add test for closing a ticket with a project bot user -
ee/spec/services/ee/issues/reopen_service_spec.rb- Add test for reopening a ticket with a project bot user -
ee/spec/workers/ee/new_issue_worker_spec.rb- Add test for ticket creation audit event (proactive)
Example spec pattern (based on existing issue tests in ee/spec/services/ee/issues/close_service_spec.rb):
context 'when closing a ticket with project bot' do
let(:service) { described_class.new(container: project, current_user: project_bot) }
let_it_be(:project_bot) { create(:user, :project_bot, email: "bot@example.com") }
let_it_be(:ticket_type) { create(:work_item_type, :ticket) }
before do
project.add_maintainer(project_bot)
end
include_examples 'audit event logging' do
let(:ticket) { create(:issue, title: "My ticket", project: project, author: project_bot, work_item_type: ticket_type) }
let(:operation) { service.execute(ticket) }
let(:event_type) { 'ticket_closed_by_project_bot' }
let(:fail_condition!) { expect(project_bot).to receive(:project_bot?).and_return(false) }
let(:attributes) do
{
author_id: project_bot.id,
entity_id: ticket.project.id,
entity_type: 'Project',
details: {
author_name: project_bot.name,
event_name: "ticket_closed_by_project_bot",
target_id: ticket.id,
target_type: 'Issue',
target_details: {
iid: ticket.iid,
id: ticket.id
}.to_s,
author_class: project_bot.class.name,
custom_message: "Closed ticket #{ticket.title}"
}
}
end
end
end
4. Verify the fix
- Manually test closing a Service Desk ticket via API with a project access token
- Manually test closing a Service Desk ticket via API with a group access token
- Verify audit event is recorded in the project's audit events
- Verify no 500 error is returned
Files to Create
| File | Purpose |
|---|---|
ee/config/audit_events/types/ticket_closed_by_project_bot.yml |
Audit event definition for closing tickets |
ee/config/audit_events/types/ticket_reopened_by_project_bot.yml |
Audit event definition for reopening tickets |
ee/config/audit_events/types/ticket_created_by_project_bot.yml |
Audit event definition for creating tickets (proactive) |
Files to Update
| File | Change |
|---|---|
doc/user/compliance/audit_event_types.md |
Auto-generated via rake task |
ee/spec/services/ee/issues/close_service_spec.rb |
Add ticket-specific audit event test |
ee/spec/services/ee/issues/reopen_service_spec.rb |
Add ticket-specific audit event test |
ee/spec/workers/ee/new_issue_worker_spec.rb |
Add ticket-specific audit event test (proactive) |