The storage meter's trough was black, which is most of the bar
Reported twice, and the first fix missed it. That pass corrected every foreground and left the trough at rgba(0,0,0,0.28) with a black inset shadow, on the reas...
The dock was reserving space for its own scrollbar, and walking left
A docked window crept left in 38px steps and then jumped back to the right edge, over and over, for as long as it was open. `rightEdgeReserve` accepts a scroll...
Remove the mock desktop dialog, and guard against it coming back
The celebration layer's corner alert reproduced a named third party's interface chrome — its title bar gradient, its double bevel, its close box — and said the ...
Round the artwork's corners
The picture sat square inside a pane with a 16px corner, cutting a rectangle out of the glass. 12px on the wrapper — the same radius the drop veil uses — and th...
Make the cabinet as tall as its own content
The page was dark for one screenful and then white for the rest of the scroll. `PageWrapper` is `height: 100%` with `flex-direction: column`, so every route in...
The white band under the cabinet
The application's `body` and `html` are `--background: #ffffff`, and this route is the one dark surface in it. The page element is `min-height: 100%` so it fill...
Every foreground on the storage meter is white
Reported unreadable, and it was. Four places went dark or coloured where the rest of the component is white on a dark ground: - The "Add 10 GB" button was #0b0...
A scrollbar 17px in from the edge is still a scrollbar the dock must not cover
The tool dock reserved the right edge for a page's vertical scrollbar only when that bar was AT the edge — within two pixels, for sub-pixel rounding. Almost no ...
The Accounts app was billed as Human Resources, so the Free plan lost it
The `accounts` option was gated on `organization.isHrs && VIEW_EMPLOYEES`. Neither half is what /account is: its own backend enforces VIEW_ACCOUNTS (CRM) on the...
The baseline award was two transactions, not one
`ensureBaselineFor` calls `ensureBaseline` on `this`, and Spring's transaction advice is a PROXY — a self-invocation does not pass through it, so the inner REQU...
Three React Compiler errors, and what each of them was really saying
The compiler rules caught three things in the achievement surfaces, and none of them was a style complaint. A component aliased into a local during render (`co...
A two-level jump published two frames and the browser kept one
`useMediaTopic` holds ONE message slot and overwrites it, so two frames arriving in the same tick are batched by React into a single render and only the last is...
The docked row has one height, and no way left to arrive at another
Resizing a docked window's top edge moves every window's top edge — the row sits on the bottom with its tops in a line, and a row of different heights is a ragg...
A redacted status event kept its type, and pin the redaction
Two things, both found by writing the test for the actorName path rather than by reading it. messageType was being read off the body AFTER redaction. redactEve...
The launchpad hid the App Shelf to say the member had no apps
A member granted an app or two and no widget right — Support and the Knowledge Base, say — opened their launchpad to "No apps yet. You don't have access to any ...
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 meeting link the member can set, and one guest row per guest
Two halves of "Add external guest to meetings does not send an email to that person". The link. meetingUrl came back from the API, was bound to nothing, and co...
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 callback can carry the link to the call
The lead page composes a callback in the calendar's own dialog, and every field that dialog collects is meant to survive the trip through here. meetingUrl did n...
Stop telling people to add the text provider they already added
Reported from a real setup, and the report was right. An organization running FreePBX added Telnyx as a text provider, opened the SMS window, and was shown Free...
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 ...
Tell a member the number is missing, not that their PBX cannot text
Reported from a real setup: an organization added Telnyx as a text provider, opened the SMS window, and was told "This phone server is a FreePBX PBX, which carr...
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...
A knowledge-base link the member can actually click
The assistant's KB links did nothing at all. Not a wrong path and not a rights problem — the click handler was never called, because no click event was ever dis...
The unread-chat card opened the member's mailbox
It carried deepLink: '/messages', which is the mail client. Chat has no route to point at — its window is a tool raised by a tool:open event — so the card navig...
A frozen CHECK blocked every Telnyx AND JustCall provider from being created
Adding a Telnyx text provider 500'd. The log named it plainly and the screen said nothing useful: constraint **************** Failing row contains (..., 6)...
The wallpaper was painting under the body, not failing to load
The launchpad backdrop — the plain gradient, the org watermark and the wallpaper slideshow it carries — has been completely invisible since 03743d02. Nothing fa...
A price Stripe has never heard of is a fault, not a silence
The reconciler compared mapped prices against the catalogue and returned early whenever nothing was mapped at all. So a term the catalogue had gained since the ...
An expired card can no longer be the one you are billed to
Answering "is changing the default still there on Payment Info" — it was, and reading it turned up a defect worth more than the answer: nothing stopped an EXPIR...
Forward carrier SMS webhooks, which reached nothing at all
Traefik sends every path on api.kamocrm.com to this gateway with no path split, and this class forwarded /api/voip/** and nothing else. So /api/bulktext/inbound...
Forward carrier SMS webhooks, which reached nothing at all
Traefik sends every path on api.kamocrm.com to this gateway with no path split, and this class forwarded /api/voip/** and nothing else. So /api/bulktext/inbound...
A NUL byte in two source files, which made git call them binary
Caught on a last pass over my own work: `billingDraft.ts` committed as "Bin 0 -> 6882 bytes". A separator written as a space had reached the file as a raw NUL b...
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...
Stop the presence gate silencing every mail notification
A member with a live MediaService socket was treated as having already seen every non-call push, mail included. That is true of what travels on that socket — a ...
Pay without leaving the order, and never lose it again
Sending somebody to another page to add a card was the wrong answer, and it was wrong at the worst possible moment. The console noticed there was no card and li...
The app shell was capping every page under every scrollbar
My last fix was in the wrong file. Removing the stacking context from the launchpad changed nothing, because the one that matters is a level above it, in the sh...
Ask whether THIS NUMBER can text, not whether the org can
SmsGateway grew a number-aware availability() when routing moved onto the number, and then nothing called it with a number — both SmsController call sites used ...
The commitment term travels with the plan, not just the plan
Carrying the plan code alone was half a fix, and the missing half was the half that carries the price. Somebody who set three years on /myplan, saw $49 a seat a...
Opening an attachment no longer throws React #310
Clicking a thumbnail threw "Minified React error #310 — rendered more hooks than during the previous render" over the whole page. Mine, from the attachment-aut...
The "you cannot text" message stopped one step short of the fix
FreePBX and Teams told a member to add an SMS provider under Phone → Providers. That was complete advice until numbers gained their own text route; now adding a...
Only the carrier that owns a webhook URL may verify its posts
The phone-server inbound path added in the previous commit verified against whatever provider carried the number. That is a forgery surface, and not hypothetica...
A Telnyx phone server could send texts and never receive one
Telnyx is both a phone server and a carrier, and a Telnyx messaging profile has exactly one webhook URL. So an organization that added Telnyx as a PHONE SERVER ...
One price on the screen, and a purchase that cannot fail silently
The console showed a customer three different numbers for one plan and let them buy with no card. Rendering it against the live catalogue, Business at five seat...
Stop the launchpad capping its own dropdowns under every scrollbar
The admin bar's dropdowns were painting under the App Shelf's scrollbar, and lowering the shelf's z-index last time did not help — because the number was never ...
Charge what the screen says, and refuse rather than pretend
An audit of the Plans & Billing console against live Stripe keys found the seam between the screen and Stripe broken in every direction at once, and silent in a...
Populate a new number before persisting it, not after
save() built an empty OrgPhoneNumber, persisted it, and then filled in E164 and PHONE_CANON — both NOT NULL. It works today because the UUID generator needs no ...
Attachments authenticate like chat's, instead of showing broken
Every attachment on a bug report rendered as a broken tile. In production: seven content requests, seven 401s, zero successes — while the report's own JSON load...
Anchor it to the first cell, and stop the scrollbar collapsing it
Three things, and two of them are the same mistake: asking a question about a portalled element as though it were a child. THE SCROLLBAR COLLAPSED THE PANE. Sc...
One source of truth, and a build that can actually reach it
Every price on this site had a second copy in the repo, and the second copy was the one being served. kamo-prices.ts said so in its own comment: the fallback t...
Drop the frozen type_id CHECK that blocked every bug thread
`media_sessions` is created by Hibernate's ddl-auto, not by a migration, so it carries the constraint ddl-auto writes for an `@Enumerated(ORDINAL)` column — fro...
Like what you see shipping?
Every one of these updates lands in your workspace automatically. Start free and watch it grow week after week.