Skip to content

fix(dingtalk): skip group messages outside the whitelist instead of crashing - #3284

Merged
zhayujie merged 1 commit into
zhayujie:masterfrom
Lesereingrape:fix/dingtalk-group-context-none-guard
Sep 29, 2026
Merged

zhayujie merged 1 commit into
zhayujie:masterfrom
Lesereingrape:fix/dingtalk-group-context-none-guard

Conversation

@Lesereingrape

@Lesereingrape Lesereingrape commented Sep 28, 2026 •

Copy link
Copy Markdown
Contributor

Fixes #3283

What does this PR do?

handle_group() assigned context['no_need_at'] = True one line above its own if context: guard. ChatChannel._compose_context() returns None when the group is not in group_name_white_list (channel/chat_channel.py, the branch that logs No need reply, groupName not in whitelist), so instead of skipping the message it raised TypeError: 'NoneType' object does not support item assignment. The fix moves the assignment inside the guard — one line, no other branch touched.

Type of change

  • Bug fix
  • New feature
  • Docs
  • Refactor / chore

Why it is a real defect

  • The None return is the base class's documented contract, and the private twin right above already honours it: handle_single() composes the context and then checks if context: (channel/dingtalk/dingtalk_channel.py:727-732). handle_group() was the only place in the channel that wrote into the value before checking it, and the next method, _maybe_attach_dingtalk_stream(), even guards if not context: return context — so the code right below was already written for a None it never got to see.
  • The crash is not just noise in the log. process() catches it and answers AckMessage.STATUS_SYSTEM_EXCEPTION, while _check has already stored the message id in receivedMsgs (channel/dingtalk/dingtalk_channel.py:88-91), so DingTalk's redelivery of that message is deduplicated and dropped. The group member receives nothing at all.
  • With the shipped defaults this is the normal path, not an edge case: config.py:71 sets "group_name_white_list": ["group1", "group2"], so on a fresh install every DingTalk group message hits it and the whitelist feature cannot be used on this channel.

What changed

channel/dingtalk/dingtalk_channel.py: context['no_need_at'] = True moved from before if context: to the first statement inside it. Behaviour for a whitelisted group is unchanged — the flag is still set before produce(), which is what channel/chat_channel.py:301 reads to decide whether a group reply needs an @.

tests/test_dingtalk_group_context_guard.py (new, no network, no SDK):

  • test_group_message_without_a_context_is_skipped — _compose_context returning None (what the base class really returns for a non-whitelisted group) must not raise and must not produce a turn.
  • test_whitelisted_group_message_still_marks_no_need_at — control: a real context is still marked no_need_at and still reaches produce().

Both reuse the _bare_channel / _context helpers and the dingtalk_stream stub from tests/test_dingtalk_streaming_cards.py, so no optional dependency is added.

How I checked it

  • Before the change, on 4c00ca6d: 1 failed, 1 passed — the failure is exactly TypeError: 'NoneType' object does not support item assignment at dingtalk_channel.py:807.
  • After the change: 2 passed; the whole DingTalk area is 34 passed (pytest tests/ -q -k dingtalk).
  • Whole suite: 36 failed, 2066 passed, 34 skipped vs 36 failed, 2064 passed, 34 skipped on the same base commit with the branch reverted, and the 36 names are identical — those are pre-existing failures on Windows, none of them in channel/dingtalk.
  • ruff check channel/dingtalk/dingtalk_channel.py tests/test_dingtalk_group_context_guard.py --select F --ignore F403,F405: all checks passed.

Checklist

…rashing

ChatChannel._compose_context returns None when the group name is not in
group_name_white_list, and every channel guards with `if context:` before
touching it. handle_group wrote context['no_need_at'] one line above that
guard, so a skipped group message raised TypeError instead of being skipped.
process() swallows it into STATUS_SYSTEM_EXCEPTION while _check has already
recorded the message id, so the redelivered message is deduplicated and the
group member never gets an answer.
@zhayujie
zhayujie merged commit 37da1a9 into zhayujie:master Sep 29, 2026
3 checks passed
@zhayujie

Copy link
Copy Markdown
Owner

Merged, thanks for the fix!

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

DingTalk: a group message outside group_name_white_list raises TypeError instead of being skipped

2 participants