fix(api): mirror assignees β assignee_ids so Lark DM actually fires#13
Merged
JOBYINC merged 1 commit intoMay 20, 2026
Merged
Conversation
β¦l-task create The actual Lark notification path is NOT model_activity / webhook fan-out (PR #12 was based on a wrong hypothesis). Lark DMs are dispatched inline from `issue_activity` itself: after IssueActivity rows are bulk_create'd, `dispatch_lark_for_activities` walks the rows and fires `notify_issue_assigned_task.delay` for any row with `field="assignees"` + `new_identifier=<user>`. That assignee row is only created when `create_issue_activity` calls `track_assignees`, and the gate at issue_activities_task.py:581 is: if requested_data.get("assignee_ids") is not None: ... The plane/api IssueSerializer uses `assignees` as its write key (vs. the plane/app variant which uses `assignee_ids`). personal_task.py forwards the request body as-is, so the gate never fires for the system-token create path β no assignee IssueActivity row β no Lark DM, even though `LARK_NOTIFICATIONS_ENABLED=1` and the worker correctly received the issue_activity task (verified in prod logs). Fix: mirror `payload["assignees"]` to `payload["assignee_ids"]` in the dict passed to `issue_activity.delay`. The serializer.save() above still consumes `assignees` (the serializer key it knows about); only the activity tracker payload is augmented. Adds a contract test that asserts the requested_data sent to issue_activity includes `assignee_ids` matching the resolved owner β the precise contract the gate at line 581 needs. PATCH path is unaffected: `update_issue_activity` ATTRIBUTE_MAPPER already maps both `"assignees"` and `"assignee_ids"` to track_assignees.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
PR #12 was based on a wrong hypothesis (the task brief said "strongly suspect model_activity"; that was wrong). Real Lark fan-out path:
The
plane/api/serializers/issue.IssueSerializerusesassigneesas its write key. Theplane/app/serializers/issue.IssueCreateSerializer(used by the web UI) usesassignee_ids. The activity tracker's gate hard-codesassignee_ids, so the system-token create path never triggers track_assignees and never produces an assignee row for the Lark dispatcher to fan out.Fix (3 lines): when building the payload for
issue_activity.delay(...), mirrorassigneesintoassignee_idsso the gate fires. The serializer.save() above is untouched β it still consumes the originalassigneeskey.Evidence from prod (before this fix)
LARK_NOTIFICATIONS_ENABLED=1is set in bothplane-api-1andplane-worker-1containers. Worker logs showissue_activitytask received with the correctissue.activity.createdpayload β butrequested_dataonly has\"assignees\": [β¦], not\"assignee_ids\":{\"type\": \"issue.activity.created\", \"requested_data\": \"{β¦, \\\"assignees\\\": [\\\"92184β¦\\\"]}\", β gate at line 581 misses β¦}No
notify_issue_assigned_taskis fired downstream.Why this matters
model_activityaddition is harmless / correct-for-webhook-subscribers but does NOT trigger the Lark DM (different code path entirely).Files
apps/api/plane/api/views/personal_task.pyβ aliasassignees β assignee_idsin theactivity_payloadpassed toissue_activity.delay. Comment explains the gate.apps/api/plane/tests/contract/api/test_personal_tasks.pyβ addstest_post_requested_data_includes_assignee_ids_for_lark_gatewhich asserts the precise contract the gate needs.Test plan
pytest plane/tests/contract/api/test_personal_tasks.py -vβ 15 passed (was 14 before round 2).assigneeskey.card_issue_assigned.