Skip to content

feat(seer): Clear Seer automation handoff preferences on integration deletion#113337

Open
srest2021 wants to merge 7 commits intomasterfrom
srest2021/AIML-2771
Open

feat(seer): Clear Seer automation handoff preferences on integration deletion#113337
srest2021 wants to merge 7 commits intomasterfrom
srest2021/AIML-2771

Conversation

@srest2021
Copy link
Copy Markdown
Member

@srest2021 srest2021 commented Apr 17, 2026

Fixes AIML-2771

When an OrganizationIntegration is deleted, any project preferences that reference it via automation_handoff are left with a dangling integration_id, and cleared the next time autofix tries to access it and throws IntegrationNotFound.

Here we add a task that fires on integration deletion and clears the handoff from all affected project preferences. A Seer API failure leaves both the Sentry DB and Seer DB in sync.

@linear-code
Copy link
Copy Markdown

linear-code bot commented Apr 17, 2026

@github-actions github-actions bot added the Scope: Backend Automatically applied to PRs that change backend components label Apr 17, 2026
project_id
for project_id, handoff_integration_id in project_handoff_integration_ids
if handoff_integration_id == integration_id
]
Copy link
Copy Markdown
Member Author

@srest2021 srest2021 Apr 17, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This fn can be greatly simplified once we finish the settings migration. We can skip straight from here to L195.

For now, we have to get all project preferences for this org, because reading from Seer doesn't allow us to know which projects are affected beforehand.

@github-actions
Copy link
Copy Markdown
Contributor

Backend Test Failures

Failures on 9dc0af7 in this run:

tests/sentry/runner/commands/test_deletions.py::DeletionsCliTest::test_run_alllog
[gw0] linux -- Python 3.13.1 /home/runner/work/sentry/sentry/.venv/bin/python3
tests/sentry/runner/commands/test_deletions.py:82: in test_run_all
    assert "Done" in rv.output
E   AssertionError: assert 'Done' in 'Running 1 deletion(s)...\nRunning deletion 9 (OrganizationIntegration #9)...\n  Failed: Cannot call or spawn apply_async in CONTROL,\n  Deletion record preserved for retry. Re-run to continue.\n'
E    +  where 'Running 1 deletion(s)...\nRunning deletion 9 (OrganizationIntegration #9)...\n  Failed: Cannot call or spawn apply_async in CONTROL,\n  Deletion record preserved for retry. Re-run to continue.\n' = <Result okay>.output
tests/sentry/runner/commands/test_deletions.py::DeletionsCliTest::test_run_by_idlog
[gw0] linux -- Python 3.13.1 /home/runner/work/sentry/sentry/.venv/bin/python3
tests/sentry/runner/commands/test_deletions.py:67: in test_run_by_id
    assert "Done" in rv.output
E   AssertionError: assert 'Done' in 'Running deletion 15 (OrganizationIntegration #15)...\n  Failed: Cannot call or spawn apply_async in CONTROL,\n  Deletion record preserved for retry. Re-run to continue.\n'
E    +  where 'Running deletion 15 (OrganizationIntegration #15)...\n  Failed: Cannot call or spawn apply_async in CONTROL,\n  Deletion record preserved for retry. Re-run to continue.\n' = <Result okay>.output
tests/sentry/runner/commands/test_deletions.py::DeletionsCliTest::test_run_by_modellog
[gw0] linux -- Python 3.13.1 /home/runner/work/sentry/sentry/.venv/bin/python3
tests/sentry/runner/commands/test_deletions.py:75: in test_run_by_model
    assert "Done" in rv.output
E   AssertionError: assert 'Done' in 'Running 1 deletion(s)...\nRunning deletion 21 (OrganizationIntegration #21)...\n  Failed: Cannot call or spawn apply_async in CONTROL,\n  Deletion record preserved for retry. Re-run to continue.\n'
E    +  where 'Running 1 deletion(s)...\nRunning deletion 21 (OrganizationIntegration #21)...\n  Failed: Cannot call or spawn apply_async in CONTROL,\n  Deletion record preserved for retry. Re-run to continue.\n' = <Result okay>.output
tests/sentry/integrations/models/deletions/test_organizationintegration.py::DeleteOrganizationIntegrationTest::test_actions_disabled_on_integration_deletelog
[gw0] linux -- Python 3.13.1 /home/runner/work/sentry/sentry/.venv/bin/python3
src/sentry/tasks/base.py:206: in wrapped
    return func(*args, **kwargs)
src/sentry/deletions/tasks/scheduled.py:110: in run_deletion_control
    _run_deletion(
src/sentry/deletions/tasks/scheduled.py:200: in _run_deletion
    has_more = task.chunk()
src/sentry/deletions/base.py:230: in chunk
    self.delete_bulk(queryset)
src/sentry/deletions/base.py:159: in delete_bulk
    self.delete_instance_bulk(instance_list)
src/sentry/deletions/base.py:168: in delete_instance_bulk
    self.delete_instance(instance)
src/sentry/deletions/defaults/organizationintegration.py:45: in delete_instance
    cleanup_seer_automation_handoff_for_integration.apply_async(
src/sentry/silo/base.py:165: in override
    return handler(*args, **kwargs)
src/sentry/taskworker/silolimiter.py:27: in handle
    raise self.AvailabilityError(message)
E   sentry.silo.base.SiloLimit.AvailabilityError: Cannot call or spawn apply_async in CONTROL,

During handling of the above exception, another exception occurred:
tests/sentry/integrations/models/deletions/test_organizationintegration.py:157: in test_actions_disabled_on_integration_delete
    run_scheduled_deletions_control()
.venv/lib/python3.13/site-packages/taskbroker_client/task.py:92: in __call__
    return self._func(*args, **kwargs)
src/sentry/deletions/tasks/scheduled.py:64: in run_scheduled_deletions_control
    _run_scheduled_deletions(
src/sentry/deletions/tasks/scheduled.py:94: in _run_scheduled_deletions
    process_task.delay(deletion_id=item.id)
src/sentry/silo/base.py:157: in override
    return original_method(*args, **kwargs)
.venv/lib/python3.13/site-packages/taskbroker_client/task.py:101: in delay
    self.apply_async(args=args, kwargs=kwargs)
src/sentry/silo/base.py:157: in override
    return original_method(*args, **kwargs)
.venv/lib/python3.13/site-packages/taskbroker_client/task.py:131: in apply_async
    self._call_func(*args, **kwargs)
.venv/lib/python3.13/site-packages/taskbroker_client/task.py:140: in _call_func
    self._func(*args, **kwargs)
src/sentry/tasks/base.py:238: in wrapped
    retry_task(exc, raise_on_no_retries=raise_on_no_retries)
.venv/lib/python3.13/site-packages/taskbroker_client/retry.py:58: in retry_task
    raise RetryTaskError()
E   taskbroker_client.retry.RetryTaskError
tests/sentry/integrations/models/deletions/test_organizationintegration.py::DeleteOrganizationIntegrationTest::test_codeowner_linkslog
[gw0] linux -- Python 3.13.1 /home/runner/work/sentry/sentry/.venv/bin/python3
src/sentry/tasks/base.py:206: in wrapped
    return func(*args, **kwargs)
src/sentry/deletions/tasks/scheduled.py:110: in run_deletion_control
    _run_deletion(
src/sentry/deletions/tasks/scheduled.py:200: in _run_deletion
    has_more = task.chunk()
src/sentry/deletions/base.py:230: in chunk
    self.delete_bulk(queryset)
src/sentry/deletions/base.py:159: in delete_bulk
    self.delete_instance_bulk(instance_list)
src/sentry/deletions/base.py:168: in delete_instance_bulk
    self.delete_instance(instance)
src/sentry/deletions/defaults/organizationintegration.py:45: in delete_instance
    cleanup_seer_automation_handoff_for_integration.apply_async(
src/sentry/silo/base.py:165: in override
    return handler(*args, **kwargs)
src/sentry/taskworker/silolimiter.py:27: in handle
    raise self.AvailabilityError(message)
E   sentry.silo.base.SiloLimit.AvailabilityError: Cannot call or spawn apply_async in CONTROL,

During handling of the above exception, another exception occurred:
tests/sentry/integrations/models/deletions/test_organizationintegration.py:120: in test_codeowner_links
    run_scheduled_deletions_control()
.venv/lib/python3.13/site-packages/taskbroker_client/task.py:92: in __call__
    return self._func(*args, **kwargs)
src/sentry/deletions/tasks/scheduled.py:64: in run_scheduled_deletions_control
    _run_scheduled_deletions(
src/sentry/deletions/tasks/scheduled.py:94: in _run_scheduled_deletions
    process_task.delay(deletion_id=item.id)
src/sentry/silo/base.py:157: in override
    return original_method(*args, **kwargs)
.venv/lib/python3.13/site-packages/taskbroker_client/task.py:101: in delay
    self.apply_async(args=args, kwargs=kwargs)
src/sentry/silo/base.py:157: in override
    return original_method(*args, **kwargs)
.venv/lib/python3.13/site-packages/taskbroker_client/task.py:131: in apply_async
    self._call_func(*args, **kwargs)
.venv/lib/python3.13/site-packages/taskbroker_client/task.py:140: in _call_func
    self._func(*args, **kwargs)
src/sentry/tasks/base.py:238: in wrapped
    retry_task(exc, raise_on_no_retries=raise_on_no_retries)
.venv/lib/python3.13/site-packages/taskbroker_client/retry.py:58: in retry_task
    raise RetryTaskError()
E   taskbroker_client.retry.RetryTaskError
tests/sentry/integrations/models/deletions/test_organizationintegration.py::DeleteOrganizationIntegrationTest::test_repository_and_identitylog
[gw0] linux -- Python 3.13.1 /home/runner/work/sentry/sentry/.venv/bin/python3
src/sentry/tasks/base.py:206: in wrapped
    return func(*args, **kwargs)
src/sentry/deletions/tasks/scheduled.py:110: in run_deletion_control
    _run_deletion(
src/sentry/deletions/tasks/scheduled.py:200: in _run_deletion
    has_more = task.chunk()
src/sentry/deletions/base.py:230: in chunk
    self.delete_bulk(queryset)
src/sentry/deletions/base.py:159: in delete_bulk
    self.delete_instance_bulk(instance_list)
src/sentry/deletions/base.py:168: in delete_instance_bulk
    self.delete_instance(instance)
src/sentry/deletions/defaults/organizationintegration.py:45: in delete_instance
    cleanup_seer_automation_handoff_for_integration.apply_async(
src/sentry/silo/base.py:165: in override
    return handler(*args, **kwargs)
src/sentry/taskworker/silolimiter.py:27: in handle
    raise self.AvailabilityError(message)
E   sentry.silo.base.SiloLimit.AvailabilityError: Cannot call or spawn apply_async in CONTROL,

During handling of the above exception, another exception occurred:
tests/sentry/integrations/models/deletions/test_organizationintegration.py:87: in test_repository_and_identity
    run_scheduled_deletions_control()
.venv/lib/python3.13/site-packages/taskbroker_client/task.py:92: in __call__
    return self._func(*args, **kwargs)
src/sentry/deletions/tasks/scheduled.py:64: in run_scheduled_deletions_control
    _run_scheduled_deletions(
src/sentry/deletions/tasks/scheduled.py:94: in _run_scheduled_deletions
    process_task.delay(deletion_id=item.id)
src/sentry/silo/base.py:157: in override
    return original_method(*args, **kwargs)
.venv/lib/python3.13/site-packages/taskbroker_client/task.py:101: in delay
    self.apply_async(args=args, kwargs=kwargs)
src/sentry/silo/base.py:157: in override
    return original_method(*args, **kwargs)
.venv/lib/python3.13/site-packages/taskbroker_client/task.py:131: in apply_async
    self._call_func(*args, **kwargs)
.venv/lib/python3.13/site-packages/taskbroker_client/task.py:140: in _call_func
    self._func(*args, **kwargs)
src/sentry/tasks/base.py:238: in wrapped
    retry_task(exc, raise_on_no_retries=raise_on_no_retries)
.venv/lib/python3.13/site-packages/taskbroker_client/retry.py:58: in retry_task
    raise RetryTaskError()
E   taskbroker_client.retry.RetryTaskError
tests/sentry/integrations/models/deletions/test_organizationintegration.py::DeleteOrganizationIntegrationTest::test_simplelog
[gw0] linux -- Python 3.13.1 /home/runner/work/sentry/sentry/.venv/bin/python3
src/sentry/tasks/base.py:206: in wrapped
    return func(*args, **kwargs)
src/sentry/deletions/tasks/scheduled.py:110: in run_deletion_control
    _run_deletion(
src/sentry/deletions/tasks/scheduled.py:200: in _run_deletion
    has_more = task.chunk()
src/sentry/deletions/base.py:230: in chunk
    self.delete_bulk(queryset)
src/sentry/deletions/base.py:159: in delete_bulk
    self.delete_instance_bulk(instance_list)
src/sentry/deletions/base.py:168: in delete_instance_bulk
    self.delete_instance(instance)
src/sentry/deletions/defaults/organizationintegration.py:45: in delete_instance
    cleanup_seer_automation_handoff_for_integration.apply_async(
src/sentry/silo/base.py:165: in override
    return handler(*args, **kwargs)
src/sentry/taskworker/silolimiter.py:27: in handle
    raise self.AvailabilityError(message)
E   sentry.silo.base.SiloLimit.AvailabilityError: Cannot call or spawn apply_async in CONTROL,

During handling of the above exception, another exception occurred:
tests/sentry/integrations/models/deletions/test_organizationintegration.py:40: in test_simple
    run_scheduled_deletions_control()
.venv/lib/python3.13/site-packages/taskbroker_client/task.py:92: in __call__
    return self._func(*args, **kwargs)
src/sentry/deletions/tasks/scheduled.py:64: in run_scheduled_deletions_control
    _run_scheduled_deletions(
src/sentry/deletions/tasks/scheduled.py:94: in _run_scheduled_deletions
    process_task.delay(deletion_id=item.id)
src/sentry/silo/base.py:157: in override
    return original_method(*args, **kwargs)
.venv/lib/python3.13/site-packages/taskbroker_client/task.py:101: in delay
    self.apply_async(args=args, kwargs=kwargs)
src/sentry/silo/base.py:157: in override
    return original_method(*args, **kwargs)
.venv/lib/python3.13/site-packages/taskbroker_client/task.py:131: in apply_async
    self._call_func(*args, **kwargs)
.venv/lib/python3.13/site-packages/taskbroker_client/task.py:140: in _call_func
    self._func(*args, **kwargs)
src/sentry/tasks/base.py:238: in wrapped
    retry_task(exc, raise_on_no_retries=raise_on_no_retries)
.venv/lib/python3.13/site-packages/taskbroker_client/retry.py:58: in retry_task
    raise RetryTaskError()
E   taskbroker_client.retry.RetryTaskError

@github-actions
Copy link
Copy Markdown
Contributor

Backend Test Failures

Failures on 1c89c7a in this run:

tests/sentry/runner/commands/test_deletions.py::DeletionsCliTest::test_run_alllog
[gw1] linux -- Python 3.13.1 /home/runner/work/sentry/sentry/.venv/bin/python3
tests/sentry/runner/commands/test_deletions.py:82: in test_run_all
    assert "Done" in rv.output
E   AssertionError: assert 'Done' in 'Running 1 deletion(s)...\nRunning deletion 9 (OrganizationIntegration #9)...\n  Failed: Cannot call or spawn apply_async in CONTROL,\n  Deletion record preserved for retry. Re-run to continue.\n'
E    +  where 'Running 1 deletion(s)...\nRunning deletion 9 (OrganizationIntegration #9)...\n  Failed: Cannot call or spawn apply_async in CONTROL,\n  Deletion record preserved for retry. Re-run to continue.\n' = <Result okay>.output
tests/sentry/runner/commands/test_deletions.py::DeletionsCliTest::test_run_by_idlog
[gw1] linux -- Python 3.13.1 /home/runner/work/sentry/sentry/.venv/bin/python3
tests/sentry/runner/commands/test_deletions.py:67: in test_run_by_id
    assert "Done" in rv.output
E   AssertionError: assert 'Done' in 'Running deletion 15 (OrganizationIntegration #15)...\n  Failed: Cannot call or spawn apply_async in CONTROL,\n  Deletion record preserved for retry. Re-run to continue.\n'
E    +  where 'Running deletion 15 (OrganizationIntegration #15)...\n  Failed: Cannot call or spawn apply_async in CONTROL,\n  Deletion record preserved for retry. Re-run to continue.\n' = <Result okay>.output
tests/sentry/runner/commands/test_deletions.py::DeletionsCliTest::test_run_by_modellog
[gw1] linux -- Python 3.13.1 /home/runner/work/sentry/sentry/.venv/bin/python3
tests/sentry/runner/commands/test_deletions.py:75: in test_run_by_model
    assert "Done" in rv.output
E   AssertionError: assert 'Done' in 'Running 1 deletion(s)...\nRunning deletion 21 (OrganizationIntegration #21)...\n  Failed: Cannot call or spawn apply_async in CONTROL,\n  Deletion record preserved for retry. Re-run to continue.\n'
E    +  where 'Running 1 deletion(s)...\nRunning deletion 21 (OrganizationIntegration #21)...\n  Failed: Cannot call or spawn apply_async in CONTROL,\n  Deletion record preserved for retry. Re-run to continue.\n' = <Result okay>.output
tests/sentry/integrations/models/deletions/test_organizationintegration.py::DeleteOrganizationIntegrationTest::test_actions_disabled_on_integration_deletelog
[gw0] linux -- Python 3.13.1 /home/runner/work/sentry/sentry/.venv/bin/python3
src/sentry/tasks/base.py:206: in wrapped
    return func(*args, **kwargs)
src/sentry/deletions/tasks/scheduled.py:110: in run_deletion_control
    _run_deletion(
src/sentry/deletions/tasks/scheduled.py:200: in _run_deletion
    has_more = task.chunk()
src/sentry/deletions/base.py:230: in chunk
    self.delete_bulk(queryset)
src/sentry/deletions/base.py:159: in delete_bulk
    self.delete_instance_bulk(instance_list)
src/sentry/deletions/base.py:168: in delete_instance_bulk
    self.delete_instance(instance)
src/sentry/deletions/defaults/organizationintegration.py:45: in delete_instance
    cleanup_seer_automation_handoff_for_integration.apply_async(
src/sentry/silo/base.py:165: in override
    return handler(*args, **kwargs)
src/sentry/taskworker/silolimiter.py:27: in handle
    raise self.AvailabilityError(message)
E   sentry.silo.base.SiloLimit.AvailabilityError: Cannot call or spawn apply_async in CONTROL,

During handling of the above exception, another exception occurred:
tests/sentry/integrations/models/deletions/test_organizationintegration.py:157: in test_actions_disabled_on_integration_delete
    run_scheduled_deletions_control()
.venv/lib/python3.13/site-packages/taskbroker_client/task.py:92: in __call__
    return self._func(*args, **kwargs)
src/sentry/deletions/tasks/scheduled.py:64: in run_scheduled_deletions_control
    _run_scheduled_deletions(
src/sentry/deletions/tasks/scheduled.py:94: in _run_scheduled_deletions
    process_task.delay(deletion_id=item.id)
src/sentry/silo/base.py:157: in override
    return original_method(*args, **kwargs)
.venv/lib/python3.13/site-packages/taskbroker_client/task.py:101: in delay
    self.apply_async(args=args, kwargs=kwargs)
src/sentry/silo/base.py:157: in override
    return original_method(*args, **kwargs)
.venv/lib/python3.13/site-packages/taskbroker_client/task.py:131: in apply_async
    self._call_func(*args, **kwargs)
.venv/lib/python3.13/site-packages/taskbroker_client/task.py:140: in _call_func
    self._func(*args, **kwargs)
src/sentry/tasks/base.py:238: in wrapped
    retry_task(exc, raise_on_no_retries=raise_on_no_retries)
.venv/lib/python3.13/site-packages/taskbroker_client/retry.py:58: in retry_task
    raise RetryTaskError()
E   taskbroker_client.retry.RetryTaskError
tests/sentry/integrations/models/deletions/test_organizationintegration.py::DeleteOrganizationIntegrationTest::test_codeowner_linkslog
[gw0] linux -- Python 3.13.1 /home/runner/work/sentry/sentry/.venv/bin/python3
src/sentry/tasks/base.py:206: in wrapped
    return func(*args, **kwargs)
src/sentry/deletions/tasks/scheduled.py:110: in run_deletion_control
    _run_deletion(
src/sentry/deletions/tasks/scheduled.py:200: in _run_deletion
    has_more = task.chunk()
src/sentry/deletions/base.py:230: in chunk
    self.delete_bulk(queryset)
src/sentry/deletions/base.py:159: in delete_bulk
    self.delete_instance_bulk(instance_list)
src/sentry/deletions/base.py:168: in delete_instance_bulk
    self.delete_instance(instance)
src/sentry/deletions/defaults/organizationintegration.py:45: in delete_instance
    cleanup_seer_automation_handoff_for_integration.apply_async(
src/sentry/silo/base.py:165: in override
    return handler(*args, **kwargs)
src/sentry/taskworker/silolimiter.py:27: in handle
    raise self.AvailabilityError(message)
E   sentry.silo.base.SiloLimit.AvailabilityError: Cannot call or spawn apply_async in CONTROL,

During handling of the above exception, another exception occurred:
tests/sentry/integrations/models/deletions/test_organizationintegration.py:120: in test_codeowner_links
    run_scheduled_deletions_control()
.venv/lib/python3.13/site-packages/taskbroker_client/task.py:92: in __call__
    return self._func(*args, **kwargs)
src/sentry/deletions/tasks/scheduled.py:64: in run_scheduled_deletions_control
    _run_scheduled_deletions(
src/sentry/deletions/tasks/scheduled.py:94: in _run_scheduled_deletions
    process_task.delay(deletion_id=item.id)
src/sentry/silo/base.py:157: in override
    return original_method(*args, **kwargs)
.venv/lib/python3.13/site-packages/taskbroker_client/task.py:101: in delay
    self.apply_async(args=args, kwargs=kwargs)
src/sentry/silo/base.py:157: in override
    return original_method(*args, **kwargs)
.venv/lib/python3.13/site-packages/taskbroker_client/task.py:131: in apply_async
    self._call_func(*args, **kwargs)
.venv/lib/python3.13/site-packages/taskbroker_client/task.py:140: in _call_func
    self._func(*args, **kwargs)
src/sentry/tasks/base.py:238: in wrapped
    retry_task(exc, raise_on_no_retries=raise_on_no_retries)
.venv/lib/python3.13/site-packages/taskbroker_client/retry.py:58: in retry_task
    raise RetryTaskError()
E   taskbroker_client.retry.RetryTaskError
tests/sentry/integrations/models/deletions/test_organizationintegration.py::DeleteOrganizationIntegrationTest::test_repository_and_identitylog
[gw0] linux -- Python 3.13.1 /home/runner/work/sentry/sentry/.venv/bin/python3
src/sentry/tasks/base.py:206: in wrapped
    return func(*args, **kwargs)
src/sentry/deletions/tasks/scheduled.py:110: in run_deletion_control
    _run_deletion(
src/sentry/deletions/tasks/scheduled.py:200: in _run_deletion
    has_more = task.chunk()
src/sentry/deletions/base.py:230: in chunk
    self.delete_bulk(queryset)
src/sentry/deletions/base.py:159: in delete_bulk
    self.delete_instance_bulk(instance_list)
src/sentry/deletions/base.py:168: in delete_instance_bulk
    self.delete_instance(instance)
src/sentry/deletions/defaults/organizationintegration.py:45: in delete_instance
    cleanup_seer_automation_handoff_for_integration.apply_async(
src/sentry/silo/base.py:165: in override
    return handler(*args, **kwargs)
src/sentry/taskworker/silolimiter.py:27: in handle
    raise self.AvailabilityError(message)
E   sentry.silo.base.SiloLimit.AvailabilityError: Cannot call or spawn apply_async in CONTROL,

During handling of the above exception, another exception occurred:
tests/sentry/integrations/models/deletions/test_organizationintegration.py:87: in test_repository_and_identity
    run_scheduled_deletions_control()
.venv/lib/python3.13/site-packages/taskbroker_client/task.py:92: in __call__
    return self._func(*args, **kwargs)
src/sentry/deletions/tasks/scheduled.py:64: in run_scheduled_deletions_control
    _run_scheduled_deletions(
src/sentry/deletions/tasks/scheduled.py:94: in _run_scheduled_deletions
    process_task.delay(deletion_id=item.id)
src/sentry/silo/base.py:157: in override
    return original_method(*args, **kwargs)
.venv/lib/python3.13/site-packages/taskbroker_client/task.py:101: in delay
    self.apply_async(args=args, kwargs=kwargs)
src/sentry/silo/base.py:157: in override
    return original_method(*args, **kwargs)
.venv/lib/python3.13/site-packages/taskbroker_client/task.py:131: in apply_async
    self._call_func(*args, **kwargs)
.venv/lib/python3.13/site-packages/taskbroker_client/task.py:140: in _call_func
    self._func(*args, **kwargs)
src/sentry/tasks/base.py:238: in wrapped
    retry_task(exc, raise_on_no_retries=raise_on_no_retries)
.venv/lib/python3.13/site-packages/taskbroker_client/retry.py:58: in retry_task
    raise RetryTaskError()
E   taskbroker_client.retry.RetryTaskError
tests/sentry/integrations/models/deletions/test_organizationintegration.py::DeleteOrganizationIntegrationTest::test_simplelog
[gw0] linux -- Python 3.13.1 /home/runner/work/sentry/sentry/.venv/bin/python3
src/sentry/tasks/base.py:206: in wrapped
    return func(*args, **kwargs)
src/sentry/deletions/tasks/scheduled.py:110: in run_deletion_control
    _run_deletion(
src/sentry/deletions/tasks/scheduled.py:200: in _run_deletion
    has_more = task.chunk()
src/sentry/deletions/base.py:230: in chunk
    self.delete_bulk(queryset)
src/sentry/deletions/base.py:159: in delete_bulk
    self.delete_instance_bulk(instance_list)
src/sentry/deletions/base.py:168: in delete_instance_bulk
    self.delete_instance(instance)
src/sentry/deletions/defaults/organizationintegration.py:45: in delete_instance
    cleanup_seer_automation_handoff_for_integration.apply_async(
src/sentry/silo/base.py:165: in override
    return handler(*args, **kwargs)
src/sentry/taskworker/silolimiter.py:27: in handle
    raise self.AvailabilityError(message)
E   sentry.silo.base.SiloLimit.AvailabilityError: Cannot call or spawn apply_async in CONTROL,

During handling of the above exception, another exception occurred:
tests/sentry/integrations/models/deletions/test_organizationintegration.py:40: in test_simple
    run_scheduled_deletions_control()
.venv/lib/python3.13/site-packages/taskbroker_client/task.py:92: in __call__
    return self._func(*args, **kwargs)
src/sentry/deletions/tasks/scheduled.py:64: in run_scheduled_deletions_control
    _run_scheduled_deletions(
src/sentry/deletions/tasks/scheduled.py:94: in _run_scheduled_deletions
    process_task.delay(deletion_id=item.id)
src/sentry/silo/base.py:157: in override
    return original_method(*args, **kwargs)
.venv/lib/python3.13/site-packages/taskbroker_client/task.py:101: in delay
    self.apply_async(args=args, kwargs=kwargs)
src/sentry/silo/base.py:157: in override
    return original_method(*args, **kwargs)
.venv/lib/python3.13/site-packages/taskbroker_client/task.py:131: in apply_async
    self._call_func(*args, **kwargs)
.venv/lib/python3.13/site-packages/taskbroker_client/task.py:140: in _call_func
    self._func(*args, **kwargs)
src/sentry/tasks/base.py:238: in wrapped
    retry_task(exc, raise_on_no_retries=raise_on_no_retries)
.venv/lib/python3.13/site-packages/taskbroker_client/retry.py:58: in retry_task
    raise RetryTaskError()
E   taskbroker_client.retry.RetryTaskError

@srest2021 srest2021 marked this pull request as ready for review April 17, 2026 19:37
@srest2021 srest2021 requested review from a team as code owners April 17, 2026 19:37
candidate_project_ids = [
project_id
for project_id, handoff_integration_id in project_handoff_integration_ids
if handoff_integration_id == integration_id
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: The comparison handoff_integration_id == integration_id may fail due to a type mismatch, as handoff_integration_id could be a string while integration_id is an integer.
Severity: MEDIUM

Suggested Fix

Ensure type consistency before the comparison. Cast handoff_integration_id to an integer, for example by changing the comparison to int(handoff_integration_id) == integration_id. This will guarantee that the comparison is between two integers.

Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent. Verify if this is a real issue. If it is, propose a fix; if not, explain why it's
not valid.

Location: src/sentry/tasks/seer/cleanup.py#L152

Potential issue: In the cleanup task, `project_handoff_integration_ids` are retrieved
using `values_list()` on a `LegacyTextJSONField`. It is possible that `values_list()`
returns the raw string value from the database (e.g., `"123"`) instead of a deserialized
integer. This would cause the comparison `handoff_integration_id == integration_id` to
always evaluate to false, as it would be comparing a string to an integer. Consequently,
no projects would be selected for cleanup, causing the task to fail silently when the
`organizations:seer-project-settings-read-from-sentry` feature flag is enabled.

Did we get this right? 👍 / 👎 to inform future reviews.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Scope: Backend Automatically applied to PRs that change backend components

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant