Skip to content

DROID-77263: fix empty-login boot-loop panic in dummybridge#10

Merged
Fizzadar merged 2 commits into
mainfrom
nick/droid-77263-empty-login-panic
Jun 15, 2026
Merged

DROID-77263: fix empty-login boot-loop panic in dummybridge#10
Fizzadar merged 2 commits into
mainfrom
nick/droid-77263-empty-login-panic

Conversation

@Fizzadar

Copy link
Copy Markdown
Member

Summary

Fixes a host-app boot-loop crash (DROID-77263) caused by logging into dummybridge with an empty username.

An empty username persisted a UserLogin with ID == "". With split portals enabled (Beeper SDK local bridges), the portal-generation goroutine in DummyClient.Connect built a PortalKey{Receiver: ""}, and Bridge.GetPortalByKey rejected it with receiver must always be set when split portals is enabled. The goroutine's bare panic(err) then crashed the whole SDK process — and the host Android app — on every startup, since the bad login row persists.

This is the approved two-layer fix ("do changes 1+2 only"):

  • Change 1 — pkg/connector/login.go: never persist an empty login ID. The login form advertises "anything goes and it's used as the ID", so an empty username is preserved by substituting a random ID rather than being rejected. This prevents an empty receiver at the source.
  • Change 2 — pkg/connector/client.go: replace the bare panic(err) in the Connect goroutine with a logged error plus an UNKNOWN_ERROR bridge-state report, then return. Defense in depth — a bad/persistent login error can never crash the host app, including any pre-existing ID == "" logins already in the database.

Testing

  • go build ./pkg/connector/... passes; go vet and gofmt clean.

Out of scope

Recovery of already-broken installs / upstream mautrix-go empty-ID validation (Change 3 in the triage plan) is intentionally not included, per the autofix directive.

Linear: https://linear.app/beeper/issue/DROID-77263

🤖 Generated with Claude Code

Nick Mills-Barrett and others added 2 commits June 15, 2026 13:27
An empty username persisted a UserLogin with ID=="". With split portals
enabled, the empty receiver makes GetPortalByKey fail on every startup.
Substitute a random ID for empty usernames so the login ID can never be
empty, while keeping the form's "anything goes" contract.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
A bare panic(err) in the portal-generation goroutine turned any persistent
error into a boot-loop crash of the host app. Report an UNKNOWN_ERROR bridge
state and return instead, so a bad login can never crash the host.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@linear-code

linear-code Bot commented Jun 15, 2026

Copy link
Copy Markdown

DROID-77263

@coderabbitai

coderabbitai Bot commented Jun 15, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: ec885f05-cfa8-4554-ba21-5c3430702efc

📥 Commits

Reviewing files that changed from the base of the PR and between f732d6a and 32b981c.

📒 Files selected for processing (2)
  • pkg/connector/client.go
  • pkg/connector/login.go
📜 Recent review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: build-docker-dummybridge
  • GitHub Check: build-docker-dummybridge
🔇 Additional comments (3)
pkg/connector/login.go (2)

9-9: LGTM!


152-163: LGTM!

pkg/connector/client.go (1)

120-130: LGTM!


📝 Walkthrough

Summary by CodeRabbit

  • Bug Fixes
    • Connection errors during portal generation are now handled gracefully with detailed error state notifications including specific error codes, instead of causing application crashes
    • Username input validation has been enhanced to automatically sanitize entries and generate valid identifiers when empty values are submitted

Walkthrough

Two defensive fixes in the dummy connector: SubmitUserInput now generates a random dummy-... ID when the submitted username is empty, and Connect's portal-generation goroutine replaces a panic with a logged BridgeState error event followed by a clean return.

Changes

Dummy Connector Defensive Fixes

Layer / File(s) Summary
Login username fallback generation
pkg/connector/login.go
Adds strings import; SubmitUserInput extracts username from input and, when empty, generates a dummy- + random lowercase string ID before passing it to dl.User.NewLogin.
Portal generation error handling in Connect
pkg/connector/client.go
Replaces panic(err) in the Connect goroutine with an error log and a BridgeState.Send call carrying StateUnknownError, error code dummy-generate-portal-failed, and the error message, then returns to halt further portal generation.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~8 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely summarizes the main change: fixing an empty-login boot-loop panic in dummybridge, which directly corresponds to the changeset's primary objective.
Description check ✅ Passed The description is comprehensive and directly related to the changeset, explaining the root cause, the two-layer fix, testing, and out-of-scope items with clear reference to the issue tracker.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch nick/droid-77263-empty-login-panic

Comment @coderabbitai help to get the list of available commands and usage tips.

@Fizzadar Fizzadar marked this pull request as ready for review June 15, 2026 16:50
@indent

indent Bot commented Jun 15, 2026

Copy link
Copy Markdown
PR Summary

Fixes DROID-77263, two related host-app crash paths in dummybridge that fired whenever a login was persisted with an empty UserLogin.ID (e.g. an empty username from the password form). After this PR an empty username is replaced with a random dummy-<id> so split-portal GetPortalByKey(Receiver: "") no longer fails, and the portal-generation goroutine in Connect reports a StateUnknownError bridge state instead of panicing the host process.

  • pkg/connector/login.go: substitute "dummy-" + strings.ToLower(random.String(12)) when input["username"] is empty before constructing the UserLogin; non-empty input is unchanged.
  • pkg/connector/client.go: replace panic(err) in the post-login portal goroutine with log.Err(...) + BridgeState.Send(StateUnknownError, "dummy-generate-portal-failed", err.Error()) + return; the context.Canceled early-return path is preserved.

Issues

No issues found.

CI Checks

Waiting for CI checks...

@Fizzadar Fizzadar merged commit c06ff59 into main Jun 15, 2026
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant