Skip to content

fix(server): device-reconcile adopts orphan connections + web bump#714

Merged
buremba merged 3 commits into
mainfrom
fix/device-reconcile-orphan-adoption
May 14, 2026
Merged

fix(server): device-reconcile adopts orphan connections + web bump#714
buremba merged 3 commits into
mainfrom
fix/device-reconcile-orphan-adoption

Conversation

@buremba
Copy link
Copy Markdown
Member

@buremba buremba commented May 14, 2026

Summary

  • Server fix: reconcileDeviceCapabilities (worker poll auto-wire) couldn't repair a device-connector row whose created_by didn't match the polling user. Both the fast-path JOIN and the slow-path reuse-check filtered by c.created_by = \${userId}, so an orphan row (e.g. created_by IS NULL from older reconcile code, or rows inserted by lobu apply with a no-user token) was invisible. The fall-through INSERT then collided with the orphan's slug, aborted the txn, and the pin never landed. Result: the row sat unpinned forever and the UI hid it (sidebar device-grouping requires device_worker_id).
    • Drop the created_by predicate from both lookups — match on (org, connector_key, auth_profile_id IS NULL, deleted_at IS NULL) instead. There's at most one such row per org, so no ambiguity.
    • When the adopted row has created_by IS NULL, backfill it under the lock so /api/me/devices and friends start attributing it correctly.
  • Web submodule bump (4d9a17f) for lobu-ai/owletto-web#105 — borderless inline pages + /$owner/events redirect.

Hit this against buremba's whatsapp.local (connection id 361, created_by was NULL, never got a pin). Backfilled prod with the explicit pin + owner so the row is usable immediately; the code fix prevents new orphans from getting stranded the same way.

Test plan

  • Worker poll from Lobu for Mac auto-wires + pins a fresh whatsapp.local connection in a new org (no orphan in the DB) — unchanged behaviour.
  • Same flow with a pre-existing whatsapp.local row whose created_by is NULL or a different user — the row is adopted, device_worker_id set, created_by backfilled.
  • make build-packages + bun run typecheck clean.
  • Web changes (border cleanup + /$owner redirect) load via the bumped submodule.

Summary by CodeRabbit

  • Bug Fixes

    • Enhanced device-connector reconciliation to better identify and reuse connections during installation and wiring workflows. Previously orphaned or unattached connections can now be properly adopted by users, streamlining the connection management and setup process.
  • Chores

    • Updated web subproject reference.

Review Change Stack

buremba added 2 commits May 14, 2026 02:13
…bmodule

When a device-connector row's created_by didn't match the polling user
(e.g. created_by IS NULL on rows inserted by older reconcile versions,
or a `lobu apply` call whose token had no user identity), the auto-wire
fast-path JOIN filtered it out, the slow-path reuse-check did the same,
and the fall-through INSERT collided with the orphan's slug — the txn
aborted and the pin never got applied. Every subsequent poll repeated
the same dance, so the UI stayed permanently broken for that org.

Drop the `c.created_by = ${userId}` predicate from both the fast-path
JOIN and the slow-path reuse-check. The device-connector identity is
(org_id, connector_key, auth_profile_id IS NULL, deleted_at IS NULL) —
exactly one such row per org, no ambiguity to disambiguate by owner.
When adopting an orphan, also backfill `created_by` so per-user
queries (e.g. /api/me/devices) start attributing the connection
correctly.

Also bumps the web submodule to pick up the inline-page border cleanup
+ /$owner -> /events redirect (lobu-ai/owletto#105).
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 14, 2026

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: b175c26c-5b5b-4ebb-953c-2531d9bf1d27

📥 Commits

Reviewing files that changed from the base of the PR and between f732081 and 860d565.

📒 Files selected for processing (2)
  • packages/server/src/worker-api/device-reconcile.ts
  • packages/web

📝 Walkthrough

Walkthrough

Device-connector reconciliation now identifies no-auth connections by auth_profile_id IS NULL instead of creator ownership. Both the fast-path readiness check and the transactional connection reuse logic were updated to match this identity, with optional backfill of creator attribution when adopting orphaned connections. The web submodule reference was also bumped to a new commit.

Changes

Device Connection Reconciliation

Layer / File(s) Summary
No-auth connection identity in fast-path and reuse
packages/server/src/worker-api/device-reconcile.ts
Fast-path readiness check and locked transaction reuse both switch from matching created_by = userId to matching auth_profile_id IS NULL, with automatic backfill of created_by when the matched connection had no creator.

Web Submodule Update

Layer / File(s) Summary
Web submodule pointer update
packages/web
Submodule reference updated to a new commit hash.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Poem

🐰 No auth needed, just NULL to see—
Connections find their way so free,
Fast paths rush and trans­actions mend,
Shared installs now transcend.
Web submodule hops ahead with glee! 🎉

✨ 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 fix/device-reconcile-orphan-adoption

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint skipped: no ESLint configuration detected in root package.json. To enable, add eslint to devDependencies.


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

@buremba buremba merged commit 76fc6e9 into main May 14, 2026
4 checks passed
@buremba buremba deleted the fix/device-reconcile-orphan-adoption branch May 14, 2026 01:23
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 69118ff9c9

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines 92 to 96
LEFT JOIN connections c
ON c.organization_id = cd.organization_id
AND c.connector_key = cd.key
AND c.created_by = ${userId}
AND c.auth_profile_id IS NULL
AND c.deleted_at IS NULL
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Preserve device owner when adopting no-auth connections

In a shared workspace where two users have devices advertising the same device connector, this join now matches any live no-auth connection for the org/connector, including one already pinned to another user's device. The fast path then calls reconcilePin on that row, and because the other device id is not in the current user's matchingDeviceIds, it can rewrite connections.device_worker_id to the polling user's device; subsequent polls from the original user can flip it back, stranding or misattributing runs/feeds. Scope adoption to true orphan/unpinned rows or keep the current user's ownership/device constraint.

Useful? React with 👍 / 👎.

@codecov-commenter
Copy link
Copy Markdown

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants