The latest updates, improvements, and fixes to Suga.
Hitting ctrl+z while typing in a sheet used to undo your last canvas edit instead of fixing your typo. Same story for redo and a handful of other shortcuts that fired when you didn't mean them to. Canvas shortcuts now stay out of the way while you're typing.
If you tried to import a repo you'd just pushed commits to, you might have seen it show up as "empty" and refuse to import, leaving you stuck with no obvious way forward. Fixed now.
Worth sharing the lesson: the GitHub API exposes a size field on each repo, and size === 0 is a tempting shortcut for detecting empty ones. It isn't reliable. That field is updated by a background job on GitHub's side that can lag by up to an hour, so a repo you just pushed to can still report zero size well after the fact. We now detect empties at the branch-fetch stage instead: no branches, no commits, nothing to import. Repos with actual content sail through, regardless of what size claims.
If you noticed your build log freezing mid-build, that wasn't you. Fixed now, along with a couple of related quirks.
Handful of UI improvements:
A round of fixes to how nodes behave on the deployment canvas:
Switched environment variable masking from native input type toggling to CSS-based masking. This fixes cross-browser inconsistencies where some browsers would offer to save masked values as passwords or interfere with copy/paste behavior.
Fixed several canvas viewport issues:
Resource names are now validated before deployment to catch naming issues early. Previously, invalid names (too long, unsupported characters) would only fail at deployment with cryptic error messages. Now you get clear feedback in the UI before you deploy.
We fixed several issues where Google Translate broke the Suga dashboard for users with auto-translate enabled in their browser.
Google Translate works by walking the DOM and replacing TextNode elements with <font> elements containing the translated text. This is fundamentally incompatible with React, which maintains references to the original DOM nodes. When React tries to update or remove a node that Google Translate already replaced, two things happen:
TextNode, but that node is no longer in the DOM. The translated <font> element stays unchanged, so dynamic content like form values and status indicators stop updating.removeChild on a node that Google Translate already removed, it throws a NotFoundError that can crash the entire component tree.Martijn Hols wrote an excellent deep dive on this exact issue, which informed our approach.
We took two approaches:
translate="no" attributes on interactive elements and dynamic content: dialog inputs, endpoint URLs, form fields, and status text that updates in real-time. This tells Google Translate to leave those nodes alone while still translating static UI labels and descriptions.
Wrapping conditional TextNodes in <span> elements. When React conditionally renders a text node (e.g., {isLoading ? "Loading..." : "Done"}), Google Translate can replace the bare TextNode before React swaps it out, causing the removeChild crash. Wrapping these in a <span> gives React a stable parent element to work with, which solved a large chunk of the crashes.
This is not a perfect solution (as the blog post explains, there is no complete fix for this incompatibility), but it protects the critical paths where stale or broken content would cause real problems.
Fixed an issue where long-running deployments could time out and lose their connection to the deployment stream. Deployments now maintain a stable connection throughout the entire rollout process, so you always see the final result.