Template logos come from a live theme host
resolveLogoUrls built the logo URL from the org's first domain whatever its state, so an org still setting up its domain got a logo URL that could not be fetche...
A notification raised on the wrong pod reached nobody
The broker here is enableSimpleBroker β in-heap, per pod, no relay β and this deployment runs two replicas. MemberNotificationService published straight into it...
The last two durable consumers become queues, and contact sync reaches every pod
The mail relay was one of four NATS subscriptions on a plain durable consumer. A plain durable admits exactly ONE subscriber, so at two replicas the second is r...
A bulk mark-read announces itself, so the nav badge follows it
The single-message endpoints have always published the mailbox events that move the nav badge and reload the other tabs. The three batch endpoints β flags, move...
Every pod relays the mailbox push, so the unread badge moves again
The browser's email relay bound a DURABLE NATS consumer named after the member ("email-ws-<id>"). A durable push consumer admits exactly one subscriber, so with...
A service may change a meeting's link, and the room is told
updateEvent restated the title, description, location, colour, timezone and deep link, and dropped meetingUrl β so a link added to a callback that had already b...
A preference PUT was resetting every setting it did not mention
Reported as "when I enable repeating sound it does not save". It saved. Then the next preference the member touched turned it off again β and the settings page ...
A meeting link can be set, not only read
meetingUrl has been on the entity, in EventDto and in meetingSignature for as long as the dialog has existed, and nothing could ever write it. EventRequest did ...
The join link reaches the guest's calendar, not just their inbox
An invitation carried its meeting link in the html body and nowhere else, so a guest who accepted it on Monday and opened their calendar on Friday had no way in...
Watch a mailbox for the phone, not only for the browser
An IMAP IDLE listener is the only thing that notices a message arriving; it publishes email.inbox.<addr>, which is what eventually asks MediaService to buzz a p...
Give the bug-status preview the denial block it now renders
SystemBugStatusEmail pre-renders two conditional blocks, and the admin preview has to supply both. Present and empty rather than absent: an unsupplied placehold...
A catalog bump emptied the sweep instead of failing it
Both reads the sweep depends on already sat inside a catch that logs and carries on, so a Yugabyte conflict never surfaced as an error β it surfaced as a tick t...
Prove the deploy by digest, not by tag
The previous commit stops `set image` being a silent no-op. This asserts the outcome: after the rollout, the tag is resolved to a digest at the registry and the...
A rebuild of the same commit deployed nothing and reported success
The image is tagged with the commit SHA, so rebuilding the same commit produces an identical image reference. `kubectl set image` then changes nothing, the Depl...
Stop one member reaching another's calendar integration, and stop the endpoints handing out the credential
Two defects on the /settings/integrations/member endpoints, both live and both reachable by any signed-in member. The id was the only access control. Every /me...
Create a subfolder under its parent, not beside it with a dot in its name
createFolder joined a parent to a new folder's name with a hardcoded ".". On Gmail, which separates its hierarchy with "/", that produced a top-level folder lit...
Take the folder from the query, so a Gmail folder can be addressed at all
The folder travelled as a path segment, and Gmail separates its hierarchy with "/" β its Sent folder is `[Gmail]/Sent Mail`. There is no way to put that in one ...
Report the folder separator and special-use role so Gmail's folders are recognisable
A member on Google Workspace saw every one of their folders listed under "My folders" with its raw path for a label β "[Gmail]/Sent Mail", "[Gmail]/Spam" β and ...
Stop a provider config save from discarding another form's fields
Every config panel posts only the fields it owns, flat, alongside the provider type -- the Google Workspace panel sends nothing but serviceAccountJson. PUT /api...
Stop a Yugabyte read restart from silently killing a transactional send
EmailTemplateService.sendToUser is the endpoint behind every service-to-service transactional email on the platform, and it was @Transactional over three reads:...
Let a rollout finish what the old pod was doing
Deploys replaced the only pod of each service with nothing to catch the requests in flight. Three settings, applied across the fleet: - preStop sleeps 10s befo...
Open the message, not the mailbox
The app has a route per (folder, uid). Being told about a mail and then landing on a list to hunt for it is the kind of small wrongness that makes a notificatio...
System mail must not send as a domain we do not authenticate
Transactional mail always went out as NoReply@{org primary domain} through our own relay. That is only safe while Kamo hosts the org's mail: then we control the...
Personal mailboxes read the OAuth registry, not dead config
Connecting a personal Gmail or Outlook mailbox has been building its consent URL with client_id= empty, and every attempt was refused by the provider. The cred...
Restore the transaction the attachment overload left behind
baf3c88 added an attachment parameter to sendToUser by moving the whole body into a new six-argument overload. The @Transactional stayed on the five-argument si...
Stop an attachment holding an IMAP connection open forever
getAttachment returned Jakarta Mail's lazy IMAPInputStream straight out of withStore, which puts the Store back in the pool the instant the lambda returns. Two ...
Show a pasted screenshot instead of a broken image
Jakarta Mail hands back a MIME header exactly as it arrived, folds and all: RFC 5322 lets a mail header run over several lines by breaking it at a CRLF followed...
Report a failed association at WARN, not at DEBUG
Lead association swallows its failures on purpose β a problem attaching a message must never break the sweep that was reading the mailbox β so the log line is t...
Keep the words typed after an inserted photo
The same reported message had a sign-off underneath its photo. That did not arrive either β the reading pane showed an empty body above the attachment. There i...
Let a photo attached from a phone be opened
A member sent themselves a message from an outside account with a file attached. The message arrived; the file was nowhere in it β no preview, no download link,...
Give a folder with an ampersand in its name its message count
A mailbox called "Bugs & Enhancements" showed no count in the sidebar while every folder beside it showed the right one, and the mailbox totals were short by ex...
Make a listed message searchable, not merely stored
The index is written from two directions. Opening a message runs the full indexer, which writes the row and then computes its search_vector. Listing a folder wr...
Make label: search read the table that records labels
The clause tested si.label_ids, an array column on the search index. Nothing has ever written it β labelling a message inserts into email_metadata.message_label...
Serve smart folders and labels as messages, not as index rows
Both endpoints answered out of email_metadata.search_index and handed the client what the table holds. A smart folder returned SearchIndexEntity β messageUid, f...
Stop asking Graph for a message size the legacy type lacks
Every listing for Mike@OptionOne.com returned 400 RequestBroker--ParseUri ("Could not find a property named 'size' on type **************** and the mailbox was ...
Stop the unread card offering mail that was read and deleted
The home-page unread-mail widget reads email_metadata.search_index directly β it must not spend an IMAP connection, which is the whole reason it exists β and th...
Stop two first loads provisioning two of each calendar
The launchpad paints two calendar widgets and each fetches its own feed, so two requests reached listCalendars at once. Provisioning is find-then-create, both p...
A contested primary is a 409, not a 500
The catch-all turned an expected refusal into a server error, which lost the message the member needed and made a routine conflict look like an outage in the lo...
Refuse a primary mailbox another member holds
Primary is a login identifier, so a silent takeover changes which account an address authenticates from a screen that never mentions logins. Assign still works ...
Build the org logo URL from its alias, not its domain
Transactional email is sent to real inboxes, so the header and footer logos have to resolve without any client-side theme JavaScript β they are built exactly th...
Conflict detection now finds conflicts
Delegates to findBusyForMemberInRange and excludes the event being edited in Java, where a null exclusion cannot poison a SQL predicate. The test it replaces m...
Actually move an event when its calendar is changed
The dialog has always offered a calendar picker when editing and the PUT has always carried the chosen calendarId, but updateEvent had no parameter for it β so ...
Size the pod above its own JVM heap ceiling [skip ci]
The image starts the JVM with -XX:MaxRAMPercentage=70 -XX:+AlwaysPreTouch, so the heap alone may take 70% of the container limit and pre-touch keeps every commi...
Campaigns take the bulk-email rights, like the recipient resolver already did
Bulk email was half-enforced and the halves were in different services. **************** in SecurityService has gated recipient resolution on MANAGE_BULK_EMAIL ...
Mailbox administration takes a right, and three endpoints get a session
MailboxController enforced no right at all. MANAGE_EMAIL_ACCOUNTS existed only as a checkRight in the browser and VIEW_EMAIL_ACCOUNTS was referenced nowhere, so...
Every contact endpoint takes the verb that names it
ContactRestController checked ownership carefully β orgOf, userOf, assertBookIsMine, assertGroupIsMine, and 404 rather than 403 so somebody else's id is never c...
Put a callback on a calendar the member can actually see
Callbacks were not reaching the calendar at all. This service picked the target calendar by account β findPrimaryByUser β and a user is global while a member is...
Stop envelopes claiming a consent answer nobody asked for
remoteImagesAllowed was a primitive boolean, and only the three endpoints that fetch a whole message ever assign it. The folder listing does not β answering it ...
Make event reminders actually notify someone
Three faults, one symptom. Members reported that calendar notifications did not work, and all three reasons were on this side. Reminders were never written. Th...
Like what you see shipping?
Every one of these updates lands in your workspace automatically. Start free and watch it grow week after week.