Skip to content

hey reply discards the reply prefill except addressed: drafts save with no subject, wrong sender, and no quoted original #341

Description

@tony-roslund

hey reply fetches the reply prefill but reads only addressed, so every reply draft is saved with no subject, as the wrong sender, and without the quoted original.

hey reply <id> --draft saves drafts that show as "No subject, Me → …" in HEY's Drafts. The root cause is one discarded response, and it costs three separate things.

Root cause

replyRecipientsFromServer (internal/cmd/thread_reply.go:83) calls GET /entries/{id}/replies/new.json — but keeps only Addressed:

prefilled, err := client.Entries().NewReply(ctx, entryID)
...
addressed := replyRecipients{
    To:  addressEmails(prefilled.Addressed.Directly),
    CC:  addressEmails(prefilled.Addressed.Copied),
    BCC: addressEmails(prefilled.Addressed.Blindcopied),
}

That same response is a MessageDraft, which per spec/hey.smithy:2991 also carries subject, sender and content. All three are dropped.

Verified live against GET /entries/2239921291/replies/new.json:

subject : 'Re: [SL-1705] Test Bug'
sender  : support@studioledger.app (id 215919703)
is_reply: True
content : 2502 chars (quoted original)

1. The subject cannot be sent at all (spec-level)

ReplyMessagePayload has no subject field — spec/hey.smithy:1863:

structure ReplyMessagePayload {
    @required
    content: String
}

Compare MessagePayload for compose (spec/hey.smithy:1591), where subject is @required. So the spec models the server handing you a prefilled subject on NewEntryReply, then provides no way to send it back. The round trip is broken in the model, and client.gen.go:1322 inherits it.

The server does accept it. Two POSTs to /entries/2239921291/replies.json, identical but for one field:

message[subject] Result Renders in Drafts as
omitted (what the SDK sends) 204 + Location No subject, Me → …
"Re: [SL-1705] Test Bug" 204 + Location Re: [SL-1705] Test Bug

Note this is only observable in the HTML view of /entries/drafts; the JSON index reports subject: null for every draft, and hey draft show on a reply draft hides is_reply/posting too — which is likely why it went unnoticed.

2. Replies act as the account default sender, not the prefill's

EntriesService.Reply (go/pkg/hey/entries.go:70) uses s.client.DefaultSenderID(ctx), ignoring prefilled.Sender. On an account with extenzions this is wrong: HEY resolves the acting sender to the address the thread was addressed to (here support@studioledger.app), while the CLI replies as the account owner. For anyone using HEY for Work as a shared support address, every CLI reply goes out from the wrong identity.

3. The quoted original is dropped

prefilled.Content holds HEY's quoted thread. Reply sends only the caller's content, so CLI replies lose the quote that a reply from the web app or TUI would carry.

Suggested fix

  1. Add subject: String to ReplyMessagePayload in spec/hey.smithy and regenerate.
  2. Have replyRecipientsFromServer return the whole MessageDraft, and let Reply accept subject and actingSenderID overrides defaulting to the prefill's values.
  3. Append prefilled.Content to the caller's body.

Happy to send a PR if the shape above looks right.

Environment

  • hey-cli 1.2.0 (58c83f1), hey-sdk 1312234
  • macOS 26.5.1, HEY for Work

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions