Skip to content

fix(server): bundle build copies connectors next to server.bundle.mjs#739

Merged
buremba merged 1 commit into
mainfrom
fix/server-bundle-copy-connectors
May 15, 2026
Merged

fix(server): bundle build copies connectors next to server.bundle.mjs#739
buremba merged 1 commit into
mainfrom
fix/server-bundle-copy-connectors

Conversation

@buremba
Copy link
Copy Markdown
Member

@buremba buremba commented May 15, 2026

Symptom

app.lobu.ai/<org>/connectors shows "No connectors found" on Lobu Cloud prod — the catalog scanner returns an empty list.

Root cause

packages/server/src/utils/connector-catalog.ts resolves DEFAULT_CONNECTOR_DIR_CANDIDATES relative to import.meta.dirname. In prod the server runs as /app/packages/server/dist/server.bundle.mjs, so the candidates become:

  1. /app/packages/server/dist/connectors — does not exist (the server bundle build didn't copy connectors here; only the CLI build did, in packages/cli/scripts/build.cjs).
  2. /app/connectors/src — does not exist.
  3. /app/packages/connectors — exists (the Dockerfile copies the whole packages/connectors/ dir), but it is the package root. The .ts connector files live in src/ underneath it.

getDefaultConnectorCatalogDir() returns candidate #3. listCatalogConnectorDefinitions() then readdirs it and filters to top-level *.ts — zero matches → empty catalog → "No connectors found".

In dev (make dev via tsx watch), import.meta.dirname is the source path, so candidate ../../../connectors/src correctly resolves and dev works fine.

Fix

Mirror the CLI build: after both bundles are emitted, copy packages/connectors/src to packages/server/dist/connectors. Candidate #1 now wins in prod and the server bundle is self-contained the same way lobu run already is.

Test plan

  • cd packages/server && bun run build:server — emits dist/connectors/ with 29 .ts files
  • bun run typecheck — clean
  • Deploy to prod and confirm the connectors page populates

Summary by CodeRabbit

  • Chores
    • Enhanced build process to ensure connectors are properly included in the bundled output.

Review Change Stack

In prod Docker the server runs as /app/packages/server/dist/server.bundle.mjs,
so connector-catalog's first candidate dir (<bundle dir>/connectors) didn't
exist — the CLI build copies it for `lobu run`, but the server bundle build
didn't. The scanner then fell through to /app/packages/connectors (package
root, copied wholesale by the Dockerfile) which contains no top-level .ts
files, so the catalog came back empty and app.lobu.ai/<org>/connectors
rendered "No connectors found".

Copy packages/connectors/src to packages/server/dist/connectors after both
bundles build, mirroring packages/cli/scripts/build.cjs. The server bundle
is now self-contained the same way `lobu run` already is.
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 15, 2026

📝 Walkthrough

Walkthrough

The build script is updated to copy connector source files into the bundled output during the build process. Node filesystem utilities are imported, and post-bundling logic removes any existing dist/connectors directory, creates the parent, and copies from connectors/src.

Changes

Build Connector Bundling

Layer / File(s) Summary
Connector source copy step
packages/server/scripts/build-server-bundle.mjs
Filesystem operations cpSync, existsSync, mkdirSync, rmSync are imported and used in a post-bundling step to copy ../connectors/src into ../dist/connectors, removing the destination if it already exists.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~5 minutes

Poem

A bundler's task, now more complete,
Connectors gathered, tidy and neat,
Rm the old, then copy the new,
Build artifacts fresh with a filesystem brew! 📦✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately reflects the main change—copying connectors into the server bundle's dist directory—and is concise and specific.
Description check ✅ Passed The description is comprehensive and well-structured, covering the symptom, root cause, fix, and test plan, though the final prod deployment test remains pending.
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 fix/server-bundle-copy-connectors

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.

@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!

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/server/scripts/build-server-bundle.mjs`:
- Around line 87-96: Ensure the copy step fails fast: always remove the
destination with rmSync(connectorsDest, { recursive: true, force: true }) first
to avoid stale files, then check existsSync(connectorsSrc) and throw a
descriptive Error when the source is missing instead of silently skipping; after
confirming the source exists, recreate the parent directory
(mkdirSync(dirname(connectorsDest), { recursive: true })) and use
cpSync(connectorsSrc, connectorsDest, { recursive: true }) and console.log as
before. Use the existing symbols connectorsSrc, connectorsDest, rmSync,
existsSync, mkdirSync, and cpSync to locate and update the logic.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 0879e5d2-ce93-441f-8d5b-2dede52ec883

📥 Commits

Reviewing files that changed from the base of the PR and between df759d7 and a18d9e2.

📒 Files selected for processing (1)
  • packages/server/scripts/build-server-bundle.mjs

Comment on lines +87 to +96
const connectorsSrc = join(pkgDir, '..', 'connectors', 'src');
const connectorsDest = join(pkgDir, 'dist', 'connectors');
if (existsSync(connectorsSrc)) {
if (existsSync(connectorsDest)) {
rmSync(connectorsDest, { recursive: true, force: true });
}
mkdirSync(dirname(connectorsDest), { recursive: true });
cpSync(connectorsSrc, connectorsDest, { recursive: true });
console.log(`\n=== copied connectors: ${connectorsDest}`);
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Fail fast if connector sources are missing instead of silently skipping copy.

Line 89 currently treats a missing connectors/src as success. That can ship a bundle without dist/connectors (or leave stale contents), which is exactly the failure mode this PR is fixing. Make this step deterministic: clear destination first, then throw when source is absent.

Suggested patch
 const connectorsSrc = join(pkgDir, '..', 'connectors', 'src');
 const connectorsDest = join(pkgDir, 'dist', 'connectors');
-if (existsSync(connectorsSrc)) {
-  if (existsSync(connectorsDest)) {
-    rmSync(connectorsDest, { recursive: true, force: true });
-  }
-  mkdirSync(dirname(connectorsDest), { recursive: true });
-  cpSync(connectorsSrc, connectorsDest, { recursive: true });
-  console.log(`\n=== copied connectors: ${connectorsDest}`);
-}
+if (existsSync(connectorsDest)) {
+  rmSync(connectorsDest, { recursive: true, force: true });
+}
+if (!existsSync(connectorsSrc)) {
+  throw new Error(`Missing connector sources at: ${connectorsSrc}`);
+}
+mkdirSync(dirname(connectorsDest), { recursive: true });
+cpSync(connectorsSrc, connectorsDest, { recursive: true });
+console.log(`\n=== copied connectors: ${connectorsDest}`);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/server/scripts/build-server-bundle.mjs` around lines 87 - 96, Ensure
the copy step fails fast: always remove the destination with
rmSync(connectorsDest, { recursive: true, force: true }) first to avoid stale
files, then check existsSync(connectorsSrc) and throw a descriptive Error when
the source is missing instead of silently skipping; after confirming the source
exists, recreate the parent directory (mkdirSync(dirname(connectorsDest), {
recursive: true })) and use cpSync(connectorsSrc, connectorsDest, { recursive:
true }) and console.log as before. Use the existing symbols connectorsSrc,
connectorsDest, rmSync, existsSync, mkdirSync, and cpSync to locate and update
the logic.

@buremba buremba merged commit 0358a4a into main May 15, 2026
24 of 25 checks passed
@buremba buremba deleted the fix/server-bundle-copy-connectors branch May 15, 2026 01:59
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