Skip to content

Conversation

@leoisadev8
Copy link
Member

Summary

  • Changed cd ../web && bun run build to bun --cwd ../web run build in Convex deploy command

Problem

Preview deployments failing with:

Error: NEXT_PUBLIC_CONVEX_URL is not configured

Even though we added --cmd-url-env-var-name NEXT_PUBLIC_CONVEX_URL, the environment variable wasn't reaching the Next.js build process.

Root Cause

When using cd within convex deploy --cmd '...', a new subshell is created and environment variables don't properly propagate. This is a known issue in monorepo setups.

Solution

Use bun --cwd ../web run build instead of cd ../web && bun run build. The --cwd flag changes the working directory while keeping the command in the same shell, preserving all environment variables set by Convex.

References

Test plan

  • Build succeeds on preview deployment
  • NEXT_PUBLIC_CONVEX_URL is available during build
  • App loads without configuration errors
  • Test user seeding works

🤖 Generated with Claude Code

Changed from 'cd ../web && bun run build' to 'bun --cwd ../web run build'
to prevent environment variable loss when changing directories within
the --cmd subshell.

When using `cd` within convex deploy --cmd, the NEXT_PUBLIC_CONVEX_URL
environment variable set by Convex doesn't properly propagate to the
subshell, causing "NEXT_PUBLIC_CONVEX_URL is not configured" errors.

Using --cwd keeps the command in the same shell, preserving env vars.

Fixes: Error: NEXT_PUBLIC_CONVEX_URL is not configured in preview deployments

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>
@vercel
Copy link

vercel bot commented Nov 9, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Comments Updated (UTC)
openchat-web Canceled Canceled Comment Nov 9, 2025 10:55pm

Copy link

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

Greptile Overview

Greptile Summary

Fixed preview deployment failures by changing how the working directory is set during the Convex deployment build process. The issue was that using cd ../web && bun run build within the convex deploy --cmd spawns a subshell where environment variables (specifically NEXT_PUBLIC_CONVEX_URL) don't properly propagate to the Next.js build process. The solution uses bun --cwd ../web run build instead, which changes the working directory while keeping execution in the same shell, preserving all environment variables set by Convex.

  • Replaced cd ../web && bun run build with bun --cwd ../web run build in both preview and production deployment commands
  • Ensures NEXT_PUBLIC_CONVEX_URL (set via --cmd-url-env-var-name) reaches the Next.js build
  • Fixes "Error: NEXT_PUBLIC_CONVEX_URL is not configured" on preview deployments
  • Aligns with Turborepo Convex monorepo example best practices

Confidence Score: 5/5

  • This PR is safe to merge with minimal risk - it's a well-documented fix for a known monorepo deployment issue
  • The change is minimal, well-researched, and addresses a specific, documented issue. The bun --cwd flag is the standard approach for preserving environment variables when changing directories (confirmed via bun help). The fix applies to both preview and production deployment paths consistently. References to Convex Discord discussion and Turborepo example validate the approach. No logic changes or new dependencies introduced.
  • No files require special attention - the single-line change is straightforward and properly addresses the root cause

Important Files Changed

File Analysis

Filename Score Overview
apps/server/package.json 5/5 Changed cd ../web && bun run build to bun --cwd ../web run build to preserve environment variables during Convex deployment

Sequence Diagram

sequenceDiagram
    participant CI as CI/CD (Vercel)
    participant ConvexDeploy as convex deploy
    participant Shell as Shell Process
    participant NextBuild as Next.js Build
    participant ConvexPreview as Convex previewSeed

    Note over CI: NEXT_PUBLIC_DEPLOYMENT=preview
    CI->>ConvexDeploy: Run build script
    ConvexDeploy->>ConvexDeploy: Set NEXT_PUBLIC_CONVEX_URL
    
    alt Using cd (Old - Broken)
        ConvexDeploy->>Shell: Spawn subshell with 'cd ../web && bun run build'
        Note over Shell: Environment variables lost in subshell
        Shell->>NextBuild: Execute build (missing NEXT_PUBLIC_CONVEX_URL)
        NextBuild-->>Shell: Error: NEXT_PUBLIC_CONVEX_URL not configured
    end
    
    alt Using --cwd (New - Fixed)
        ConvexDeploy->>Shell: Execute 'bun --cwd ../web run build' in same shell
        Note over Shell: Environment variables preserved
        Shell->>NextBuild: Execute build (with NEXT_PUBLIC_CONVEX_URL)
        NextBuild-->>Shell: Build successful
    end
    
    Shell-->>ConvexDeploy: Build complete
    ConvexDeploy->>ConvexPreview: Run --preview-run previewSeed
    ConvexPreview->>ConvexPreview: Create test user ([email protected])
    ConvexPreview-->>ConvexDeploy: Seed complete
    ConvexDeploy-->>CI: Deployment successful
Loading

1 file reviewed, no comments

Edit Code Review Agent Settings | Greptile

@leoisadev8 leoisadev8 force-pushed the fix/convex-env-var-propagation branch from b0516ea to c704c3d Compare November 9, 2025 22:15
@sonarqubecloud
Copy link

sonarqubecloud bot commented Nov 9, 2025

Quality Gate Failed Quality Gate failed

Failed conditions
4.1% Duplication on New Code (required ≤ 3%)

See analysis details on SonarQube Cloud

Comment on lines 10 to 27
name: Run production canary checks
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Setup Bun
uses: oven-sh/setup-bun@v1
with:
bun-version: "1.2.21"

- name: Run canary tests
env:
PROD_CONVEX_URL: ${{ secrets.CONVEX_URL }}
CANARY_TIMEOUT_MS: "15000"
CANARY_MAX_RETRIES: "5"
CANARY_RETRY_DELAY_MS: "10000"
run: bun ./scripts/prod-canary.ts

Check warning

Code scanning / CodeQL

Workflow does not contain permissions Medium

Actions job or workflow does not limit the permissions of the GITHUB_TOKEN. Consider setting an explicit permissions block, using the following as a minimal starting point: {contents: read}

Copilot Autofix

AI 6 days ago

To fix this issue, add an explicit permissions block with the correct minimal privileges. In this case, examining the workflow shows no steps require any write privileges or special tokens; they just check out code and run scripts. Thus, the least privilege needed is for reading contents. Place the permissions: contents: read block at the job level directly under prod-canary: (recommended unless you want it at workflow root, but job-level is more targeted given this warning). No other changes, imports, or definitions are needed.


Suggested changeset 1
.github/workflows/prod-canary.yml

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/.github/workflows/prod-canary.yml b/.github/workflows/prod-canary.yml
--- a/.github/workflows/prod-canary.yml
+++ b/.github/workflows/prod-canary.yml
@@ -9,6 +9,8 @@
   prod-canary:
     name: Run production canary checks
     runs-on: ubuntu-latest
+    permissions:
+      contents: read
     steps:
       - name: Checkout
         uses: actions/checkout@v4
EOF
@@ -9,6 +9,8 @@
prod-canary:
name: Run production canary checks
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- name: Checkout
uses: actions/checkout@v4
Copilot is powered by AI and may make mistakes. Always verify output.
responseMessage = messageText || "Server configuration error";
}

return new Response(responseMessage, { status, headers });

Check warning

Code scanning / CodeQL

Information exposure through a stack trace Medium

This information exposed to the user depends on
stack trace information
.

Copilot Autofix

AI 6 days ago

To prevent information exposure through error messages (and potential stack traces), the code should return only generic error messages to users, regardless of the environment. Instead of including the full error message in the HTTP response in development, the error message should be logged server-side with sufficient detail (the stack trace if available), but the response should remain generic for all users. The fix involves modifying the error-handling block (lines 385–404):

  • Always set responseMessage to a generic string, e.g., "Server configuration error", "Missing apiKey", or "Missing modelId", as appropriate, on all environment modes.
  • Remove the code path that sets responseMessage = messageText in non-production mode.
  • Ensure detailed errors (message and/or stack) are logged server-side for debugging (using logError).
  • No change is needed elsewhere; imports and existing upstream logging cover the requirement.

Suggested changeset 1
apps/web/src/app/api/chat/chat-handler.ts

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/apps/web/src/app/api/chat/chat-handler.ts b/apps/web/src/app/api/chat/chat-handler.ts
--- a/apps/web/src/app/api/chat/chat-handler.ts
+++ b/apps/web/src/app/api/chat/chat-handler.ts
@@ -385,7 +385,6 @@
 			logError("Failed to resolve model", error);
 			const headers = buildCorsHeaders(request, allowOrigin);
 			const messageText = error instanceof Error ? error.message : String(error ?? "");
-			const isProduction = process.env.NODE_ENV === "production";
 			let status = 500;
 			let responseMessage = "Server configuration error";
 
@@ -396,11 +395,10 @@
 			} else if (messageText.includes("Missing modelId")) {
 				status = 400;
 				responseMessage = "Missing modelId";
-			} else if (!isProduction) {
-				// In development, include detailed error for debugging
-				responseMessage = messageText || "Server configuration error";
 			}
 
+			// Always return only generic error messages to users, regardless of environment.
+
 			return new Response(responseMessage, { status, headers });
 		}
 
EOF
@@ -385,7 +385,6 @@
logError("Failed to resolve model", error);
const headers = buildCorsHeaders(request, allowOrigin);
const messageText = error instanceof Error ? error.message : String(error ?? "");
const isProduction = process.env.NODE_ENV === "production";
let status = 500;
let responseMessage = "Server configuration error";

@@ -396,11 +395,10 @@
} else if (messageText.includes("Missing modelId")) {
status = 400;
responseMessage = "Missing modelId";
} else if (!isProduction) {
// In development, include detailed error for debugging
responseMessage = messageText || "Server configuration error";
}

// Always return only generic error messages to users, regardless of environment.

return new Response(responseMessage, { status, headers });
}

Copilot is powered by AI and may make mistakes. Always verify output.
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