convex-backend icon indicating copy to clipboard operation
convex-backend copied to clipboard

Local dev server fails to start

Open Tyler-Petrov opened this issue 6 months ago • 22 comments

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.

Tyler-Petrov avatar May 19 '25 21:05 Tyler-Petrov

Things I've tried so far

  • Deleting the ~/.convex folder 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 ~/convex folder to 777 doesn'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.

Tyler-Petrov avatar May 21 '25 16:05 Tyler-Petrov

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.

nipunn1313 avatar May 21 '25 19:05 nipunn1313

you may also be able to get community support in the Convex discord. Lot of people there are helpful.

nipunn1313 avatar May 21 '25 19:05 nipunn1313

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!

Tyler-Petrov avatar May 21 '25 19:05 Tyler-Petrov

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.

nipunn1313 avatar May 21 '25 20:05 nipunn1313

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.

Tyler-Petrov avatar May 21 '25 21:05 Tyler-Petrov

same issue. after deleting ~/.convex and reauthenticating it says failed to load deployment config

jeevanpillay avatar Jun 13 '25 02:06 jeevanpillay

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

Image

rafay99-epic avatar Jul 29 '25 14:07 rafay99-epic

@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

thomasballinger avatar Jul 29 '25 15:07 thomasballinger

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 avatar Jul 29 '25 15:07 thomasballinger

@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"]),
});

Image

rafay99-epic avatar Jul 29 '25 15:07 rafay99-epic

Could you try this with CONVEX_VERBOSE=1 npx convex dev?

thomasballinger avatar Jul 30 '25 04:07 thomasballinger

Could you try this with CONVEX_VERBOSE=1 npx convex dev?

Sure, I ran the command and this is the output in the terminal

Image

rafay99-epic avatar Jul 30 '25 07:07 rafay99-epic

@thomasballinger This is happening all of the sudden and none of my convex project are loading now.

rafay99-epic avatar Jul 30 '25 07:07 rafay99-epic

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.

ohbob avatar Sep 23 '25 10:09 ohbob

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

rafay99-epic avatar Sep 23 '25 11:09 rafay99-epic

@ohbob Change your package manager as well, I believe I was using npm and bun, try pnpm

rafay99-epic avatar Sep 23 '25 11:09 rafay99-epic

I faced the same issue, if you have pnpm (as package manager), try running pnpm dlx convex dev instead of npx convex dev

saurav49 avatar Oct 16 '25 09:10 saurav49

Thanks for the help..

rafay99-epic avatar Oct 16 '25 15:10 rafay99-epic

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 avatar Oct 18 '25 02:10 fmaclen

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

rafay99-epic avatar Oct 18 '25 13:10 rafay99-epic

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.

fmaclen avatar Nov 04 '25 15:11 fmaclen