convex-backend
convex-backend copied to clipboard
Local dev server fails to start
The Problem
I'm having trouble running Convex locally. I run pnpx convex dev, and I get a timeout error. After running the command a few times in a row, I can usually get the local backend running, but not always. Unfortunately I don't have any good steps to reproduce, but if anyone has any suggestions I'm all ears.
My Setup
I'm on Windows 11 running Convex in the official Arch distro from MS.
The Output
[tpetrov@tylersawesomepc jairus]$ pnpx convex dev
waiting for local backend to start...
✖ Local backend did not start on port 3210 within 10 seconds.
✖ Hit an error while running local deployment.
Your error has been reported to our team, and we'll be working on it.
To opt out, run `npx convex disable-local-deployments`. Then re-run your original command.
Things I've tried so far
- Deleting the
~/.convexfolder which then the server starts fine, but obviously I don't have any data in my db, so not a valid option. - Updating the permissions of everything in the
~/convexfolder to777doesn't solve the problem.
Cry for help
I wish there was an error output saying what's up. Then I could at least diagnose the issue without shooting in the dark.
Yep - we hear ya. @thomasballinger had some ideas for automatically showing some of the logfile output in this case - but nothing implemented yet.
There's an undocumented env var https://github.com/get-convex/convex-backend/blob/e3a807988f9d51d63539fbf9c8a39f632cba50e5/crates/cmd_util/src/env.rs#L50 - CONVEX_TRACE_FILE=1 - if you set that, it should write the backend logs to a logfile to help diagnose.
Sorry for the trouble. You could also try disabling local deployments and use a cloud development server.
you may also be able to get community support in the Convex discord. Lot of people there are helpful.
I haven't had much luck on Discord, but I'll give it a shot. I was getting limited with cloud dev, so that's why I'm sticking with local for now. I'll take a look at that env var. Thanks for your help!
Yeah - the response time is likely to be quicker on discord - and more people will get eyes on it. Definitely hear ya that it's hard to make sense of what's going on.
I set the env var, and I got an output. I put the output in the discord thread, so if that's the preferred location to discuss bugs then I'll just put updates there. Thank you for your assistance! Here's a link to the discord thread.
same issue. after deleting ~/.convex and reauthenticating it says failed to load deployment config
For me, even when I delete the .convex folder in my home, I still get stuck. Any idea what might be causing this issue?
Or what is the solution to this problem? Any helps please
@rafay99-epic could you try npx instead of bun in case that's the problem? We'd like bun to work, but would be useful to narrow down. What OS? Try again like CONVEX_VERBOSE=1 npx convex dev
same issue. after deleting ~/.convex and reauthenticating it says failed to load deployment config
@jeevanpillay "failed to load deployment config" is expected if you delete your .convex folder, that's where it's stored. If you want to create a new one, delete .env.local.
@thomasballinger So I am using MacOS 15.5, and I did use npm, bun, pnpm, and yarn, all these tools, but still nothing.
here is my scheme I have build for this application
import { defineSchema, defineTable } from "convex/server";
import { v } from "convex/values";
export default defineSchema({
users: defineTable({
userId: v.string(),
email: v.string(),
firstName: v.optional(v.string()),
lastName: v.optional(v.string()),
username: v.optional(v.string()),
name: v.optional(v.string()),
profileImage: v.optional(v.string()),
country: v.string(), // User's country
serviceCategories: v.optional(v.array(v.string())), // Multi-select array for service providers
languagePreference: v.string(), // Language preference
referralCode: v.string(),
referralLink: v.string(),
referralBarcodeUrl: v.optional(v.string()), // URL to QR code image stored in Convex file storage
referredBy: v.optional(v.string()), // userId of the referrer
referredByCode: v.optional(v.string()), // The actual referral code used
referralMethod: v.optional(v.string()), // "manual", "automatic", "link", "qr"
authProvider: v.optional(v.string()), // "google", "apple", "linkedin", etc.
// New affiliate system fields
affiliateLevel: v.string(), // "L10", "L9", "L8", etc.
directReferralCount: v.float64(),
serviceProviderReferralCount: v.float64(),
isEmailVerified: v.boolean(),
pointsBreakdown: v.object({
referralPoints: v.float64(),
serviceProviderPoints: v.float64(),
signupPoints: v.float64(),
emailVerificationPoints: v.float64(),
}),
// Wake-up ping related fields
lastActiveAt: v.optional(v.float64()), // Last time user was active (login, profile update, etc.)
profileCompletionScore: v.optional(v.float64()), // Score 0-100 based on profile completeness
isProfileComplete: v.optional(v.boolean()), // Whether profile is considered complete
createdAt: v.float64(),
})
.index("by_userId", ["userId"])
.index("by_referralCode", ["referralCode"])
.index("by_affiliateLevel", ["affiliateLevel"])
.index("by_referredBy", ["referredBy"])
.index("by_country", ["country"])
.index("by_emailVerified", ["isEmailVerified"])
.index("by_createdAt", ["createdAt"])
.index("by_lastActiveAt", ["lastActiveAt"])
.index("by_authProvider", ["authProvider"])
.index("by_email", ["email"])
.index("by_affiliateLevel_country", ["affiliateLevel", "country"])
.index("by_createdAt_country", ["createdAt", "country"])
.index("by_isEmailVerified_country", ["isEmailVerified", "country"])
.index("by_referredByCode", ["referredByCode"])
.index("by_referredByCode_createdAt", ["referredByCode", "createdAt"])
.index("by_referredByCode_isEmailVerified", ["referredByCode", "isEmailVerified"]),
pointsConfig: defineTable({
type: v.string(), // "SIGNUP", "EMAIL_VERIFICATION", "USER_REFERRAL", "SERVICE_PROVIDER_REFERRAL", "SOCIAL_SIGN_IN"
points: v.float64(),
description: v.string(),
isActive: v.boolean(),
lastUpdated: v.float64(),
updatedBy: v.string(), // admin userId
})
.index("by_type", ["type"])
.index("by_isActive", ["isActive"])
.index("by_type_isActive", ["type", "isActive"]),
levelThresholds: defineTable({
level: v.string(), // "L10", "L9", "L8", etc.
requiredPoints: v.float64(),
directReferrals: v.float64(),
serviceProviders: v.float64(),
description: v.string(),
isActive: v.boolean(),
lastUpdated: v.float64(),
updatedBy: v.string(), // admin userId
})
.index("by_level", ["level"])
.index("by_isActive", ["isActive"])
.index("by_requiredPoints", ["requiredPoints"])
.index("by_level_isActive", ["level", "isActive"]),
pointsHistory: defineTable({
userId: v.string(),
pointsEarned: v.float64(),
pointsType: v.string(), // "signup", "email_verification", "referral", "service_provider_referral"
description: v.string(),
referralId: v.optional(v.string()), // Link to referral if applicable
createdAt: v.float64(),
})
.index("by_user", ["userId"])
.index("by_pointsType", ["pointsType"])
.index("by_createdAt", ["createdAt"])
.index("by_user_createdAt", ["userId", "createdAt"])
.index("by_user_pointsType", ["userId", "pointsType"])
.index("by_createdAt_pointsType", ["createdAt", "pointsType"]),
referralStats: defineTable({
userId: v.string(), // The referrer's userId
totalReferrals: v.float64(),
activeReferrals: v.float64(),
pendingReferrals: v.float64(),
totalEarnings: v.float64(),
conversionRate: v.float64(),
lastUpdated: v.float64(),
})
.index("by_user", ["userId"])
.index("by_totalReferrals", ["totalReferrals"])
.index("by_totalEarnings", ["totalEarnings"])
.index("by_lastUpdated", ["lastUpdated"]),
referralHistory: defineTable({
referrerId: v.string(),
referredId: v.string(),
referralType: v.string(),
referralMethod: v.string(),
status: v.string(),
pointsAwarded: v.float64(),
createdAt: v.float64(),
})
.index("by_referrer", ["referrerId"])
.index("by_referred", ["referredId"])
.index("by_status", ["status"])
.index("by_createdAt", ["createdAt"])
.index("by_referrer_createdAt", ["referrerId", "createdAt"])
.index("by_status_createdAt", ["status", "createdAt"]),
waitlist: defineTable({
email: v.optional(v.string()),
whatsapp: v.optional(v.string()),
type: v.string(),
createdAt: v.number(),
status: v.string(),
})
.index("by_email", ["email"])
.index("by_whatsapp", ["whatsapp"])
.index("by_type", ["type"])
.index("by_status", ["status"])
.index("by_createdAt", ["createdAt"])
.index("by_type_status", ["type", "status"])
.index("by_createdAt_status", ["createdAt", "status"]),
services: defineTable({
name: v.string(),
description: v.optional(v.string()),
isActive: v.boolean(),
createdAt: v.float64(),
updatedAt: v.float64(),
updatedBy: v.string(), // admin userId
})
.index("by_name", ["name"])
.index("by_isActive", ["isActive"])
.index("by_createdAt", ["createdAt"])
.index("by_name_isActive", ["name", "isActive"]),
posts: defineTable({
title: v.string(),
slug: v.string(),
content: v.string(), // Rich text content (HTML or JSON format)
excerpt: v.optional(v.string()), // Short summary/description
featuredImage: v.optional(v.string()), // Main featured image URL
featuredImageAlt: v.optional(v.string()), // Alt text for featured image
images: v.optional(
v.array(
v.object({
// Images used in content
url: v.string(),
alt: v.optional(v.string()),
caption: v.optional(v.string()),
})
)
),
tags: v.array(v.string()), // Array of tag names
status: v.string(), // "draft", "published", "archived"
publishedAt: v.optional(v.number()), // When post was published
readingTime: v.optional(v.number()), // Estimated reading time in minutes
views: v.optional(v.number()), // View count
seoTitle: v.optional(v.string()), // SEO title (if different from title)
seoDescription: v.optional(v.string()), // Meta description for SEO
createdAt: v.number(),
updatedAt: v.number(),
})
.index("by_slug", ["slug"])
.index("by_status", ["status"])
.index("by_tag", ["tags"])
.index("by_publishedAt", ["publishedAt"])
.index("by_createdAt", ["createdAt"])
.index("by_status_publishedAt", ["status", "publishedAt"])
.index("by_status_createdAt", ["status", "createdAt"])
.searchIndex("by_content", {
searchField: "content",
})
.searchIndex("by_title", {
searchField: "title",
}),
// Blog tags table for managing tags
blogTags: defineTable({
name: v.string(), // Tag name (unique)
slug: v.string(), // URL-friendly version
description: v.optional(v.string()), // Tag description
color: v.optional(v.string()), // Hex color for UI
postCount: v.number(), // Number of posts with this tag
createdAt: v.number(),
updatedAt: v.number(),
})
.index("by_name", ["name"])
.index("by_slug", ["slug"])
.index("by_postCount", ["postCount"])
.index("by_createdAt", ["createdAt"]),
comments: defineTable({
postId: v.id("posts"),
authorId: v.string(),
authorName: v.string(),
content: v.string(),
createdAt: v.number(),
})
.index("by_postId", ["postId"])
.index("by_authorId", ["authorId"])
.index("by_createdAt", ["createdAt"])
.index("by_postId_createdAt", ["postId", "createdAt"]),
featureFlags: defineTable({
key: v.string(),
name: v.string(),
description: v.string(),
enabled: v.boolean(),
category: v.string(),
targetAudience: v.optional(v.string()),
createdAt: v.number(),
updatedAt: v.number(),
updatedBy: v.optional(v.string()),
})
.index("by_key", ["key"])
.index("by_category", ["category"])
.index("by_enabled", ["enabled"])
.index("by_category_enabled", ["category", "enabled"])
.index("by_createdAt", ["createdAt"]),
wakeUpPings: defineTable({
affiliateId: v.string(), // userId of the affiliate sending the ping
targetUserId: v.string(), // userId of the inactive user being pinged
pingType: v.string(), // "wake_up_email"
sentAt: v.float64(), // Timestamp when ping was sent
emailSent: v.boolean(), // Whether email was successfully sent
emailError: v.optional(v.string()), // Error message if email failed
responded: v.boolean(), // Whether user responded to ping (logged in, updated profile)
respondedAt: v.optional(v.float64()), // When user responded
responseType: v.optional(v.string()), // "login", "profile_update", "verification"
})
.index("by_affiliate", ["affiliateId"])
.index("by_target", ["targetUserId"])
.index("by_affiliate_target", ["affiliateId", "targetUserId"])
.index("by_sent_date", ["sentAt"])
.index("by_responded", ["responded"])
.index("by_pingType", ["pingType"])
.index("by_sentAt_responded", ["sentAt", "responded"])
.index("by_affiliate_sentAt", ["affiliateId", "sentAt"]),
// Mini Games / Quests definition (admin managed)
miniGames: defineTable({
title: v.string(),
description: v.string(),
type: v.string(),
criteria: v.string(),
pointsReward: v.float64(),
isActive: v.boolean(),
createdAt: v.float64(),
createdBy: v.string(),
updatedAt: v.float64(),
updatedBy: v.string(),
})
.index("by_type", ["type"])
.index("by_isActive", ["isActive"])
.index("by_createdAt", ["createdAt"])
.index("by_type_isActive", ["type", "isActive"]),
// User progress and completion for mini games
userMiniGameProgress: defineTable({
userId: v.string(),
miniGameId: v.id("miniGames"),
progress: v.string(), // JSON string for flexible progress tracking
completedAt: v.optional(v.float64()),
rewardClaimed: v.boolean(),
lastUpdated: v.float64(),
})
.index("by_user", ["userId"])
.index("by_miniGame", ["miniGameId"])
.index("by_user_miniGame", ["userId", "miniGameId"])
.index("by_completedAt", ["completedAt"])
.index("by_rewardClaimed", ["rewardClaimed"])
.index("by_lastUpdated", ["lastUpdated"]),
contact_submissions: defineTable({
name: v.string(),
email: v.string(),
subject: v.string(),
message: v.string(),
createdAt: v.number(),
})
.index("by_email", ["email"])
.index("by_createdAt", ["createdAt"])
.index("by_email_createdAt", ["email", "createdAt"]),
});
Could you try this with CONVEX_VERBOSE=1 npx convex dev?
Could you try this with
CONVEX_VERBOSE=1 npx convex dev?
Sure, I ran the command and this is the output in the terminal
@thomasballinger This is happening all of the sudden and none of my convex project are loading now.
have the same problem now, yesterday everything worked, today not. @rafay99-epic did you find a solution?
great lost all my data starting the server with CONVEX_VERBOSE=1 , love this product.
have the same problem now, yesterday everything worked, today not. @rafay99-epic did you find a solution?
great lost all my data starting the server with CONVEX_VERBOSE=1 , love this product.
Yeah, the problem kind of disappeared after some time. I don't remember how this was resolved for me, but this is a real issue, I believe. For me, I logged out and then cleared all the convex files and cache, and the issue was resolved.
Yeah, don't use convex verbose=1, it will wipe everything
One more thing, change your shell, from ZSH to bash or fish shell, I never have this problem in PowerShell
@ohbob Change your package manager as well, I believe I was using npm and bun, try pnpm
I faced the same issue, if you have pnpm (as package manager), try running pnpm dlx convex dev instead of npx convex dev
Thanks for the help..
I started getting this issue after updating the CLI to 1.28.0. Tried debugging it by running CONVEX_TRACE_FILE=1 bunx convex dev --local and this is the error I was getting:
[2m2025-10-18T01:57:06.222398Z[0m [32m INFO[0m [2mnode_executor::local[0m[2m:[0m Initializing inner local node executor
[2m2025-10-18T01:57:06.224145Z[0m [32m INFO[0m [2mnode_executor::local[0m[2m:[0m Using local node executor. Source: /var/folders/g_/xmpw4_zs2f9fmg2m__tvhm880000gn/T/.tmpJTwpox/local.cjs
[2m2025-10-18T01:57:06.240053Z[0m [32m INFO[0m [2mnode_executor::local[0m[2m:[0m Starting node executor server on port 20119
[2m2025-10-18T01:57:06.396051Z[0m [33m WARN[0m [2mnode_executor::executor[0m[2m:[0m Failed to invoke analyze: Node executor server returned error: {"type":"error","message":"Invalid checksum, got vhbKs1mLuFeq4MzI_59WQxbbCYluru0OCsvIHRFTBFk, expected SEJmXOgtZPzC_x5V1WJC62Yv6eXlig03_ah1f3W754M"}
...
I deleted ~/.convex/convex-backend-state/my-db-123, reset CONVEX_DEPLOYMENT= in .env.local, then in convex.json I specified a Node version (wasn't set before):
{
"node": {
"nodeVersion": "22"
}
}
Finally, re-ran bunx convex dev --local, configured my cloud project and it generated a new local backend state without errors.
@fmaclen I believe I did the same thing and the issue was resolved becase after this day and i folowed these setup, this issue never came up.
This has happened again.
When I was trying to run my local server it told me my version was old and prompted me to update. I confirmed the update and chose to "transfer existing data" (didn't work), then retried and chose "start fresh" (also didn't work).
Looks like Node executor is failing catastrophically when the checksum changes, here's the full trace (including the Sentry id):
[2m2025-11-04T15:37:36.866660Z[0m [32m INFO[0m [2mnode_executor::local[0m[2m:[0m Starting node executor server on port 23554
[2m2025-11-04T15:37:37.028451Z[0m [33m WARN[0m [2mnode_executor::executor[0m[2m:[0m Failed to invoke analyze: Node executor server returned error: {"type":"error","message":"Invalid checksum, got IpeFyb0hnuuwLTKRsz0PPMc4_mXlD_Mp6KuzlPvjRVg, expected WPqqxK0i3CFAMfMI9ZxMhwWCSTGFlVZBQiIXRb3ArYc"}
[2m2025-11-04T15:37:37.158734Z[0m [33m WARN[0m [2mnode_executor::executor[0m[2m:[0m Failed to invoke analyze: Node executor server returned error: {"type":"error","message":"Invalid checksum, got IpeFyb0hnuuwLTKRsz0PPMc4_mXlD_Mp6KuzlPvjRVg, expected WPqqxK0i3CFAMfMI9ZxMhwWCSTGFlVZBQiIXRb3ArYc"}
[2m2025-11-04T15:37:37.370945Z[0m [33m WARN[0m [2mnode_executor::executor[0m[2m:[0m Failed to invoke analyze: Node executor server returned error: {"type":"error","message":"Invalid checksum, got IpeFyb0hnuuwLTKRsz0PPMc4_mXlD_Mp6KuzlPvjRVg, expected WPqqxK0i3CFAMfMI9ZxMhwWCSTGFlVZBQiIXRb3ArYc"}
[2m2025-11-04T15:37:37.719024Z[0m [31mERROR[0m [2mcommon::errors[0m[2m:[0m Caught error error (RUST_BACKTRACE=1 RUST_LOG=info,common::errors=debug for full trace): Hit an error while pushing:\nNode executor server returned error: {"type":"error","message":"Invalid checksum, got IpeFyb0hnuuwLTKRsz0PPMc4_mXlD_Mp6KuzlPvjRVg, expected WPqqxK0i3CFAMfMI9ZxMhwWCSTGFlVZBQiIXRb3ArYc"}: Node executor server returned error: {"type":"error","message":"Invalid checksum, got IpeFyb0hnuuwLTKRsz0PPMc4_mXlD_Mp6KuzlPvjRVg, expected WPqqxK0i3CFAMfMI9ZxMhwWCSTGFlVZBQiIXRb3ArYc"}
[2m2025-11-04T15:37:37.719032Z[0m [34mDEBUG[0m [2mcommon::errors[0m[2m:[0m Hit an error while pushing:
Node executor server returned error: {"type":"error","message":"Invalid checksum, got IpeFyb0hnuuwLTKRsz0PPMc4_mXlD_Mp6KuzlPvjRVg, expected WPqqxK0i3CFAMfMI9ZxMhwWCSTGFlVZBQiIXRb3ArYc"}
Caused by:
Node executor server returned error: {"type":"error","message":"Invalid checksum, got IpeFyb0hnuuwLTKRsz0PPMc4_mXlD_Mp6KuzlPvjRVg, expected WPqqxK0i3CFAMfMI9ZxMhwWCSTGFlVZBQiIXRb3ArYc"}
[2m2025-11-04T15:37:37.719505Z[0m [31mERROR[0m [2mcommon::errors[0m[2m:[0m Reporting above error to sentry with event_id c51c15d36fb2485183b9ced34e9bfdac
[2m2025-11-04T15:37:37.719547Z[0m [32m INFO[0m [2mconvex-cloud-http[0m[2m:[0m [] 127.0.0.1:49456 "POST /api/deploy2/start_push HTTP/1.1" 500 "-" "node" application/json - 921.177ms
I solved it again by deleting the DB completely and reset it as per my earlier comment.
For extra reference, I'm on Convex 1.28.0.