Skip to content

ref(seer): Use Protocol for FeatureDeliveryFn type

129553a
Select commit
Loading
Failed to load commit list.
Merged

feat(seer): Add deliver_feature_result RPC for Seer agent features #116734

ref(seer): Use Protocol for FeatureDeliveryFn type
129553a
Select commit
Loading
Failed to load commit list.
@sentry/warden / warden: sentry-backend-bugs completed Jun 2, 2026 in 10m 7s

2 issues

sentry-backend-bugs: Found 2 issues (1 high, 1 medium)

High

Circular import between feature_delivery.py and night_shift/delivery.py causes ImportError at startup - `src/sentry/seer/agent/feature_delivery.py:7`

Line 7 imports deliver_night_shift_result from night_shift/delivery.py, which on its own line 14 imports FeatureRunStatus back from this partially-initialized module — FeatureRunStatus is defined on line 9 (after the circular import), so Python raises ImportError: cannot import name 'FeatureRunStatus' at startup. Move FeatureRunStatus to a standalone types module (e.g. sentry/seer/agent/types.py) and import it from there in both files.

Also found at:

  • src/sentry/seer/endpoints/seer_rpc.py:63

Medium

`TriageVerdict.reason` typed as required `str` but treated as optional, silently dropping all verdicts when field is absent - `src/sentry/seer/night_shift/delivery.py:78-83`

If Seer omits the reason field (or sends null) in a verdict, pydantic raises ValidationError during TriageResponse.parse_obj(result), which the broad except Exception catches — silently discarding all verdicts for the entire run. Fix by changing reason: str to reason: str | None = None in src/sentry/seer/night_shift/models.py.


⏱ 8m 57s · 884.5k in / 53.3k out · $1.72

Annotations

Check failure on line 7 in src/sentry/seer/agent/feature_delivery.py

See this annotation in the file changed.

@sentry-warden sentry-warden / warden: sentry-backend-bugs

Circular import between feature_delivery.py and night_shift/delivery.py causes ImportError at startup

Line 7 imports `deliver_night_shift_result` from `night_shift/delivery.py`, which on its own line 14 imports `FeatureRunStatus` back from this partially-initialized module — `FeatureRunStatus` is defined on line 9 (after the circular import), so Python raises `ImportError: cannot import name 'FeatureRunStatus'` at startup. Move `FeatureRunStatus` to a standalone types module (e.g. `sentry/seer/agent/types.py`) and import it from there in both files.

Check failure on line 63 in src/sentry/seer/endpoints/seer_rpc.py

See this annotation in the file changed.

@sentry-warden sentry-warden / warden: sentry-backend-bugs

[J9F-HQZ] Circular import between feature_delivery.py and night_shift/delivery.py causes ImportError at startup (additional location)

Line 7 imports `deliver_night_shift_result` from `night_shift/delivery.py`, which on its own line 14 imports `FeatureRunStatus` back from this partially-initialized module — `FeatureRunStatus` is defined on line 9 (after the circular import), so Python raises `ImportError: cannot import name 'FeatureRunStatus'` at startup. Move `FeatureRunStatus` to a standalone types module (e.g. `sentry/seer/agent/types.py`) and import it from there in both files.

Check warning on line 83 in src/sentry/seer/night_shift/delivery.py

See this annotation in the file changed.

@sentry-warden sentry-warden / warden: sentry-backend-bugs

`TriageVerdict.reason` typed as required `str` but treated as optional, silently dropping all verdicts when field is absent

If Seer omits the `reason` field (or sends `null`) in a verdict, pydantic raises `ValidationError` during `TriageResponse.parse_obj(result)`, which the broad `except Exception` catches — silently discarding all verdicts for the entire run. Fix by changing `reason: str` to `reason: str | None = None` in `src/sentry/seer/night_shift/models.py`.