Dokploy / Dokploy/dokploy

Self-hosted dashboard fails at login with "Missing value for Stripe(): apiKey should be a string"

Open
#5,344 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
TypeScript
Stars
37.4k
Forks
3k
Avg merge
1d 3h
Merged PRs (30d)
73

Description

To Reproduce
  1. Run a self-hosted / development instance from canary (no NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY set — it isn't in apps/dokploy/.env.example).
  2. Log in.
  3. The dashboard fails to render.
Runtime IntegrationError
Missing value for Stripe(): apiKey should be a string.
Current vs. Expected behavior

Current: a self-hosted instance can't get past login. Setting NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY to any non-empty placeholder unblocks it, which is what identifies the cause.

Expected: a self-hosted instance never touches Stripe. IS_CLOUD / settings.isCloud is false, so nothing billing-related should be reachable.

What causes it

The import chain from the dashboard entry point is fully static:

apps/dokploy/pages/dashboard/home.tsx:13
  → components/dashboard/onboarding/onboarding-wizard.tsx:21
    → components/dashboard/onboarding/steps/plan-step.tsx:14

and plan-step.tsx calls Stripe at module scope, not inside the component:

const stripePromise = loadStripe(
  process.env.NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY!,
);

The guard inside the wizard is a runtime one:

const { data: isCloud = true } = api.settings.isCloud.useQuery();
const visibleStepIds = isCloud ? ... : ...;

It decides which steps render. It cannot prevent the module from being imported, so loadStripe(undefined) runs on every self-hosted instance regardless. Stripe.js then throws IntegrationError because the key isn't a string.

components/dashboard/settings/billing/show-billing.tsx:45 does the same thing at module scope, and plan-step.tsx imports from it, so there are two paths to the same call.

Introduced by 2e2e0c8c2 ("feat: cloud onboarding wizard, billing trial card, and post-checkout server setup"). Server-side billing is unaffected — getBillingStatus returns early on !IS_CLOUD before creating a Stripe client. This is client-side only.

Possible fixes, in rough order of least invasive: move loadStripe inside the component (or a useMemo) so it only runs when the plan step actually renders; or lazy-load PlanStep behind the isCloud check; or make the call tolerant of a missing key.

Provide environment information
  • Dokploy v0.30.5 (canary at 1572008c)
  • Self-hosted, Docker, macOS host, Node 26, Next.js 16.3.0 (Turbopack)
  • NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY unset, as per .env.example
Which area(s) are affected? (Select all that apply)

Dashboard / UI

Are you deploying the applications where Dokploy is installed or on a remote server?

Dokploy Server

Additional context

Found while testing a DNS provider branch rebased on canary; it reproduces on plain canary and has nothing to do with that work. Worth flagging because it affects every self-hosted instance on this version, and the error message points at Stripe rather than at the onboarding wizard, which makes it easy to misattribute.

Will you send a PR to fix it?

No

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by tracing the static imports from apps/dokploy/pages/dashboard/home.tsx through components/dashboard/onboarding/onboarding-wizard.tsx and components/dashboard/onboarding/steps/plan-step.tsx; also inspect the module-scope Stripe call in components/dashboard/settings/billing/show-billing.tsx. Reproduce login with NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY unset, then verify that self-hosted dashboard rendering no longer invokes Stripe while cloud billing and onboarding remain available.

Written by the indexing model from the issue text.

Assessment

Tech stack
nextjs, typescript
Domain
cloud, frontend
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
74/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.