Skip to content

Fix unable to edit thread replies#6410

Merged
VelikovPetar merged 2 commits intodevelopfrom
bug/AND-1169_fix_edit_reply_not_working
May 5, 2026
Merged

Fix unable to edit thread replies#6410
VelikovPetar merged 2 commits intodevelopfrom
bug/AND-1169_fix_edit_reply_not_working

Conversation

@VelikovPetar
Copy link
Copy Markdown
Contributor

@VelikovPetar VelikovPetar commented May 4, 2026

Goal

Editing a thread reply message currently fails with 400 Bad Request from the backend.

The backend's UpdateMessage endpoint validates message.type against oneof='' regular system. When a thread reply is sent, the server overwrites its type to "reply" (server-assigned). Clients then echo the full message back on edit, which includes type: "reply" — rejected by the validator before the handler runs.

The same issue affects any message whose stored type is not regular or system (reply, error, ephemeral, deleted, etc.).

Implementation

The fix lives at the network adapter layer (MoshiChatApi), which is the wire-format boundary — already responsible for similar wire-only quirks (e.g. lifting skip_push/skip_enrich_url off the domain Message). Local state is never touched.

  • DtoMapping.Message.toDto() now accepts an optional messageType: String? = null parameter. When null (default), it falls back to the message's own type — the mapper stays a pure 1:1 conversion.
  • MoshiChatApi introduces a private Message.uploadMessageType extension property that returns type only when it is MessageType.REGULAR or MessageType.SYSTEM, and "" otherwise. The empty string is accepted by the backend validator (omitempty,oneof='' regular system) and ignored on update anyway, so this is functionally lossless.
  • Both sendMessage and updateMessage pass message.uploadMessageType to toDto(). No copy of the domain Message is made, no plugin/transformer is involved.

UI Changes

Before After
edit-reply-before.mp4
edit-reply-after.mp4

Testing

Manual verification: editing a thread reply now succeeds end-to-end against the backend.

Summary by CodeRabbit

  • Bug Fixes

    • Messages are now properly validated and normalized when sent or updated, with unsupported types automatically coerced to valid backend formats.
  • Tests

    • Added test coverage for message type validation and coercion during send and update operations.

Co-Authored-By: Claude <noreply@anthropic.com>
@VelikovPetar VelikovPetar added the pr:bug Bug fix label May 4, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 4, 2026

PR checklist ✅

All required conditions are satisfied:

  • Title length is OK (or ignored by label).
  • At least one pr: label exists.
  • Sections ### Goal, ### Implementation, and ### Testing are filled.

🎉 Great job! This PR is ready for review.

@VelikovPetar VelikovPetar changed the title [AND-1169] Fix edit reply message returning 400 Fix unable to edit thread replies May 4, 2026
@VelikovPetar VelikovPetar marked this pull request as ready for review May 4, 2026 20:55
@VelikovPetar VelikovPetar requested a review from a team as a code owner May 4, 2026 20:55
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 4, 2026

SDK Size Comparison 📏

SDK Before After Difference Status
stream-chat-android-client 5.82 MB 5.82 MB 0.00 MB 🟢
stream-chat-android-ui-components 11.02 MB 11.02 MB 0.00 MB 🟢
stream-chat-android-compose 12.37 MB 12.37 MB 0.00 MB 🟢

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 4, 2026

Walkthrough

The PR enhances message serialization by introducing type coercion logic. When sendMessage and updateMessage build request DTOs, they now coerce message types to valid backend values (REGULAR, SYSTEM, or empty string) using a new uploadMessageType property before conversion.

Changes

Message Type Coercion

Layer / File(s) Summary
Data Shape & Mapping
src/main/java/io/getstream/chat/android/client/api2/mapping/DtoMapping.kt
Message.toDto() signature updated to accept optional messageType: String? = null parameter; UpstreamMessageDto.type now uses messageType ?: type to allow caller-controlled type override.
Core Implementation
src/main/java/io/getstream/chat/android/client/api2/MoshiChatApi.kt
New uploadMessageType extension property coerces message types to REGULAR, SYSTEM, or empty string based on MessageType enum; sendMessage and updateMessage now pass message.uploadMessageType to toDto().
Tests & Verification
src/test/java/io/getstream/chat/android/client/api2/MoshiChatApiTestArguments.kt, src/test/java/io/getstream/chat/android/client/api2/MoshiChatApiTest.kt, src/test/java/io/getstream/chat/android/client/api2/mapping/DtoMappingTest.kt
New uploadMessageTypeInput() test argument generator covers REGULAR and SYSTEM with string equivalents, plus REPLY, ERROR, EPHEMERAL mapping to empty string. Parameterized tests verify type coercion in sendMessage and updateMessage via argumentCaptor. Unit test confirms toDto(messageType) parameter is used correctly.

Estimated Code Review Effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Poem

Hop along, dear message stream,
Your types now coerce with gleaming dream!
From REPLY and ERROR, rest they go—
As empty strings they brightly glow! 🐰✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 7.14% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Fix unable to edit thread replies' directly reflects the main bug being addressed, which is the failure to edit thread reply messages.
Description check ✅ Passed The description covers Goal, Implementation, UI Changes with before/after videos, and Testing sections as required by the template, though some optional sections like Testing patch details and all checklist items are not fully completed.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch bug/AND-1169_fix_edit_reply_not_working

Tip

💬 Introducing Slack Agent: The best way for teams to turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
Review rate limit: 7/8 reviews remaining, refill in 7 minutes and 30 seconds.

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
stream-chat-android-client/src/test/java/io/getstream/chat/android/client/api2/MoshiChatApiTestArguments.kt (1)

116-123: ⚡ Quick win

Expand uploadMessageTypeInput() with explicit FAILED and "deleted" cases.

The new table is good, but adding the remaining known non-uploadable/server-assigned types will harden this regression suite.

Proposed test-arguments extension
     fun uploadMessageTypeInput() = listOf(
         Arguments.of(MessageType.REGULAR, MessageType.REGULAR),
         Arguments.of(MessageType.SYSTEM, MessageType.SYSTEM),
         Arguments.of(MessageType.REPLY, ""),
         Arguments.of(MessageType.ERROR, ""),
         Arguments.of(MessageType.EPHEMERAL, ""),
+        Arguments.of(MessageType.FAILED, ""),
+        Arguments.of("deleted", ""),
     )
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@stream-chat-android-client/src/test/java/io/getstream/chat/android/client/api2/MoshiChatApiTestArguments.kt`
around lines 116 - 123, The uploadMessageTypeInput() test data is missing known
non-uploadable/server-assigned types; update the function
(MoshiChatApiTestArguments.uploadMessageTypeInput) to include explicit cases for
MessageType.FAILED and the string "deleted" in the returned list so the table
covers those regression cases (i.e., add Arguments.of(MessageType.FAILED, "")
and Arguments.of("deleted", "") alongside the existing entries).
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In
`@stream-chat-android-client/src/test/java/io/getstream/chat/android/client/api2/MoshiChatApiTestArguments.kt`:
- Around line 116-123: The uploadMessageTypeInput() test data is missing known
non-uploadable/server-assigned types; update the function
(MoshiChatApiTestArguments.uploadMessageTypeInput) to include explicit cases for
MessageType.FAILED and the string "deleted" in the returned list so the table
covers those regression cases (i.e., add Arguments.of(MessageType.FAILED, "")
and Arguments.of("deleted", "") alongside the existing entries).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 9b461a57-0b87-49b2-babf-e211a70104c9

📥 Commits

Reviewing files that changed from the base of the PR and between 84b9b96 and c21d46a.

📒 Files selected for processing (5)
  • stream-chat-android-client/src/main/java/io/getstream/chat/android/client/api2/MoshiChatApi.kt
  • stream-chat-android-client/src/main/java/io/getstream/chat/android/client/api2/mapping/DtoMapping.kt
  • stream-chat-android-client/src/test/java/io/getstream/chat/android/client/api2/MoshiChatApiTest.kt
  • stream-chat-android-client/src/test/java/io/getstream/chat/android/client/api2/MoshiChatApiTestArguments.kt
  • stream-chat-android-client/src/test/java/io/getstream/chat/android/client/api2/mapping/DtoMappingTest.kt

@sonarqubecloud
Copy link
Copy Markdown

sonarqubecloud Bot commented May 5, 2026

@VelikovPetar VelikovPetar merged commit e3b06d1 into develop May 5, 2026
16 checks passed
@VelikovPetar VelikovPetar deleted the bug/AND-1169_fix_edit_reply_not_working branch May 5, 2026 12:13
@stream-public-bot stream-public-bot added the released Included in a release label May 5, 2026
@stream-public-bot
Copy link
Copy Markdown
Contributor

🚀 Available in v7.1.0

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

Labels

pr:bug Bug fix released Included in a release

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants