Tracking fixes for the top toast:show_error events identified via PostHog (last 30 days, prod builds only).
-
TypeError: undefined is not an object (i.type)—customHooks.svelte.tsnow uses RTK Queryunwrap()(272 events / 81 users) -
erro_titletypo in PostHog capture —error.ts:102 -
commitingtypo —uncommittedService.svelte.ts:233error string -
shouldIgnoreThistErrortypo —parser.ts+showError.ts - Generate branch name disabled on empty branch —
BranchHeaderContextMenu.svelte(~20 events/mo) - Rate-limit toast PostHog captures to 60/hour —
toasts.ts(caps runaway spikes; mitigates most "Failed to fetch" storms) - 401 → actionable "Login token expired. Please log in to GitButler again." —
httpClient.ts(120 events / 95 users) -
SilentErrorfor Octokit rate limiter —ratelimit.ts(~76 events)
- Path is a directory — return empty
FileInfofor directories inread_file_from_workspace(crates/gitbutler-repo/src/commands.rs:297) — 188 events / 14 users - Hunk not found while committing — skip unmatched hunks instead of throwing in
uncommittedService.svelte.ts:233— 56 events / 17 users - Failed to fetch diff eliminated — removed
throwingetUnifiedDiff, widened return type toUnifiedDiff | null, callers already handle null via optional chaining; real IPC errors still surface via RTKunwrap()— 57 events / 11 users - keychain_notfound telemetry fix —
annotate_keychain_errornow wraps withContext::new_static(Code, stable_msg)for both SecretKeychainNotFound and MissingLoginKeychain (crates/but-secret/src/secret.rs) — 23 events / 21 users (telemetry only; UI already shows friendly text)
- Generate commit message: info toast on no changes — swap
showError→ infoshowToastinmacros.svelte.ts(covers both commit-message and branch-name generation paths) — 104 events / 48 users - WSL2 / UNC guidance as info toast —
projectsService.ts:142-161now usesshowToast({style: "info"})for both unsupported-path cases — 53 events / 37 users - install_cli osascript decline as info — Rust side tags status-1 with
Code::CliInstallCancelled(but-action/src/cli.rs);GeneralSettings.sveltematches on that code and shows info toast — 32 events / 24 users - App update RO-filesystem: info toast with guidance — detect "Read-only file system" / EROFS in
updater.ts:handleErrorand show info toast linking to downloads — 14 events / 5 users
Concerns surfaced when reviewing the first round of fixes, addressed as separate commits on the same branch.
- Silent whole-file commit risk —
uncommittedService.svelte.tspushedhunkHeaders: []when every selected hunk in a file was stale, which the backend interprets as "commit whole file." Now we track stale-skip count per path and drop the file from the commit (plus an info toast) when every selection was stale. HIGH severity — potential data surprise. - Directory vs. empty-file ambiguity — introduced
FileInfo::directory()as a semantic constructor for the directory case so the read path reads cleanly; did not add a dedicated marker field because no current consumer distinguishes directories from zero-byte files, and overloadingmime_typewithinode/directorywould confuse theImageDiffrenderer that uses the field fordata:URL building. If a future caller needs to differentiate, a properis_directory: boolcan be added then. - osascript cancel string-matching — added
Code::CliInstallCancelled(errors.cli.install_cancelled), Rust side attaches it viaContext::new_static, frontend matches ongetUserErrorCode(err) === Code.CliInstallCancelledinstead of the English message. - RO-filesystem pattern English-centric / Linux-centric — broadened to cover
os error 30(Linux EROFS numeric),os error 6032(WindowsERROR_WRITE_PROTECT), and "write-protected" / "write protected" phrasing. Deliberately avoided bare "Permission denied" to prevent over-matching. - Keychain annotation Linux-only — renamed
annotate_linux_keychain→annotate_keychain_errorand attached a stable"System keychain access failed"label withCode::Unknownfor macOS/Windows + unmatched Linux paths, so PostHog aggregates these rather than bucketing every localized error separately.
- Disable AI-generate button when there are no changes — would require reactive plumbing from selection/diff state up to the toolbar. The info-toast conversion already removes the error noise; this is a UI polish follow-up.
- Modal/inline messaging for WSL2/UNC guidance — info toast conveys the guidance; a modal would be more prominent but is a UX decision for a separate design pass.
- Dedicated
Codefor macOS/Windows keychain — those platforms always have a default keychain, so a bespoke Code has no known user-facing remediation to tie to. Revisit if telemetry shows a cluster.
Context: query:error captures ~1.6M events / 14 days / 4.2k users — roughly 100× the volume of toast:show_error. Investigation (2026-04-16) showed massive single-user spam loops (one user repeatedly hitting a broken stacks / list_reviews call fires tens of thousands of times) and wide command-not-found fallout (irc_*, forge_provider) that never surfaces as a toast.
- Rate limit + per-key dedup on
emitQueryError—error.tsadds a 60-minute rolling window with an overall 200-event cap and a 5-event cap per(command, error_title)pair. Also skipsSilentErrordefensively. Expected to cutquery:errorvolume by ~100× without losing signal. - Forward
command+actionNameto capture payload —customHooks.svelte.tsnow passes the RTK endpoint context intoemitQueryError, so PostHog can group by command instead of string-parsingAPI error: (cmd)out oferror_message. This surfaces clusters like per-projectstacks/list_reviewsthat were previously fragmented across one-user buckets with project IDs embedded in the message. -
erro_titletypo confirmed fixed in source — grep shows onlyerror_titlein all four capture sites (error.ts,customHooks.svelte.ts,toasts.ts,posthog.ts). Deployed1.360.2still emits the typo because the fix rode into nightly but hasn't shipped in a stable release yet; next release will clear it. No code change needed.
- "Expected to be in edit mode" as Unhandled exception — 90 events / 36 users in 24h. Already fixed in prior work but still firing; confirmed shipped — residual is old-build tail. No code change needed.
- Git hook output shown as error toast — ~20 events / ~15 users. Hook failures were surfacing with generic "Error" title (from
Error.name) or "Unhandled exception" (from unhandled promise rejections incommitDropHandler.ts). Fix:hooksService.tsnow throws errors withname = "Git hook failed"for better PostHog grouping;commitDropHandler.tswraps hook calls in try/catch withshowError("Git hook failed", err)instead of letting them propagate as unhandled rejections. - "Git push failed" toast shows raw command params — 73 events / 31 users.
backendQuery.tswas prependingcommand: ...\nparams: {JSON}to every backend error message, burying the actual error. Fix: removed the command/params prefix — the command name is already in the errornamefield (API error: (push_stack)), and the actual error message now surfaces cleanly in the toast. - 401 Unauthorized under generic "Error" title — 8 events / 7 users. Some servers/proxies return a non-401 status code but with
{"error":"401 Unauthorized"}in the body, bypassing the status-code check. Fix:httpClient.tsparseResponseJSONnow also checks the response body for "401 Unauthorized" in the>= 400branch and shows the friendly login-expired message. - "Failed to amend commit: noEffectiveChanges" as error — 4–7 events / 1–2 users. Fix:
stackEndpoints.tscommitAmend.transformResponsenow detects when all rejections arenoEffectiveChanges, shows an info toast ("No changes to amend"), and throwsSilentErrorto suppress the error toast while still signaling mutation failure.
- Linux auto-updater "invalid updater binary format" (178 events / 103 users) — Tauri/distro issue, needs separate effort
- Various single-user repeat errors (set_project_active, Windows
R:/path, etc.) — environment-specific Expected to be in edit mode(2,811 events / 353 users) — already resolved prior to this session- IRC command-not-found spam (
irc_get_file_message_reactions,irc_get_all_commit_reactions— ~615k events / 1.8k users) — feature-flag gating on the call sites; deliberately out of scope for this round. Rate-limit changes above will already dedupe this down to ~5 events/user/hour per command. forge_providernot found / ACL-blocked (~67k events / ~5k users) — same class as IRC; new rate limit handles it.