Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
55e8a21
docs: add Stack Auth → Hexclave rebrand plan
BilalG1 May 21, 2026
0bef15f
docs: cover query params, storage keys, custom events, and dev tool i…
BilalG1 May 22, 2026
1843a37
docs: v7 — internal-only renames, env var dual-read, 3-PR rollout
BilalG1 May 22, 2026
a1d043b
docs: fold PR 1 discovery findings into the plan
BilalG1 May 22, 2026
8b7ccfc
docs: correct x-stack-auth legacy header — SDK-internal, not backend
BilalG1 May 22, 2026
e60550a
feat(hexclave): add Hexclave* SDK export aliases
BilalG1 May 22, 2026
fc781de
feat(hexclave): JWT validator accepts both stack-auth.com and hexclav…
BilalG1 May 22, 2026
2a056ea
feat(hexclave): dual-accept x-hexclave-* request headers
BilalG1 May 22, 2026
30ffd60
feat(hexclave): register ask_hexclave MCP tool alongside ask_stack_auth
BilalG1 May 22, 2026
7fed864
feat(hexclave): env vars, cookies, bearer, symbols, query params, int…
BilalG1 May 22, 2026
32131ea
feat(hexclave): rename dev-tool DOM identifiers and switch its header…
BilalG1 May 22, 2026
21217fb
fix(hexclave): review-pass fixes for PR 1
BilalG1 May 22, 2026
4b16cc5
test(hexclave): hide x-hexclave-request-id in snapshots; regen projec…
BilalG1 May 22, 2026
58199d7
feat(hexclave): regenerate OpenAPI docs for hexclave_response_mode qu…
BilalG1 May 22, 2026
6d07139
fix(hexclave): address review comment + hide duplicate hexclave heade…
BilalG1 May 22, 2026
5e5189f
fix(hexclave): SDK fallback tests — restore singular helpers, context…
BilalG1 May 22, 2026
f911217
fix(hexclave): address review comments + auth-like test helper Bearer…
BilalG1 May 22, 2026
4977c73
chore(hexclave): temporarily bump docker workflow sleep to diagnose d…
BilalG1 May 22, 2026
8a0d6f4
fix(hexclave): optimize entrypoint sentinel-replace to only sed match…
BilalG1 May 23, 2026
8ab3789
fix(docker): guard sentinel-replace against bare STACK_ENV_VAR_SENTIN…
May 23, 2026
afc8ff8
fix(lint): correct ternary indentation in parseAuthorizationHeaderValue
May 23, 2026
3d36caf
fix(hexclave): preserve stackauth_ Bearer emission; mirror URL envs i…
May 23, 2026
3f51ed5
fix(hexclave): update e2e tests for cookie dual-write + storage-key r…
BilalG1 May 23, 2026
d111c60
fix(hexclave): three more test-side follow-ups for cookie/header dual…
BilalG1 May 23, 2026
b60a455
fix(hexclave): address pr review compatibility feedback
BilalG1 May 23, 2026
dce66a8
fix(hexclave): drop duplicate Hexclave*App type re-exports
BilalG1 May 23, 2026
47e7c6e
fix(hexclave): align e2e tests with hexclave-only emit (cookies, cros…
BilalG1 May 23, 2026
3a480a3
Merge remote-tracking branch 'origin/dev' into cl/hexclave-pr1
BilalG1 May 23, 2026
5ad6888
fix(tests): align with HexclaveAssertionError suffix + hexclave_cross…
BilalG1 May 23, 2026
809ca8d
Merge branch 'dev' into cl/hexclave-pr1
BilalG1 May 23, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
3 changes: 3 additions & 0 deletions .claude/CLAUDE-KNOWLEDGE.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

This file contains knowledge learned while working on the codebase in Q&A format.

## Q: Which Hexclave rename compatibility layers should be avoided in PR #1475 follow-ups?
A: Do not keep backwards compatibility for the MCP tool name, cross-domain auth query parameter names, `NEXT_PUBLIC_STACK_PORT_PREFIX`, or a parallel `hexclaveAppInternalsSymbol`. For refresh/access cookies, read both legacy Stack and new Hexclave cookie names, but only write the canonical Hexclave cookies.

## Q: How should GitHub Contents API request-body assertions be written in Stack Auth tests?
A: Prefer inline snapshots over individual field selectors. For request bodies that contain base64 file content, parse the JSON body, assert it is an object, decode the `content` field back to UTF-8, and snapshot the normalized call object so the test verifies the path, method, headers, branch, message, sha, and rendered file content together.

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/e2e-custom-base-port-api-tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:
NODE_ENV: test
STACK_ENABLE_HARDCODED_PASSKEY_CHALLENGE_FOR_TESTING: yes
STACK_DATABASE_CONNECTION_STRING: "postgres://postgres:PASSWORD-PLACEHOLDER--uqfEC1hmmv@localhost:6728/stackframe"
NEXT_PUBLIC_STACK_PORT_PREFIX: "67"
NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX: "67"
STACK_EXTERNAL_DB_SYNC_MAX_DURATION_MS: "20000"
STACK_EXTERNAL_DB_SYNC_DIRECT: "false"

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/setup-tests-with-custom-base-port.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ jobs:
if: ${{ (github.head_ref || github.ref_name) == 'dev' }}
runs-on: ubicloud-standard-16
env:
NEXT_PUBLIC_STACK_PORT_PREFIX: "69"
NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX: "69"
STACK_EXTERNAL_DB_SYNC_MAX_DURATION_MS: "20000"
STACK_EXTERNAL_DB_SYNC_DIRECT: "false"

Expand Down
1,060 changes: 1,060 additions & 0 deletions RENAME-TO-HEXCLAVE.md

Large diffs are not rendered by default.

30 changes: 15 additions & 15 deletions apps/backend/.env.development
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
NEXT_PUBLIC_STACK_API_URL=http://localhost:${NEXT_PUBLIC_STACK_PORT_PREFIX:-81}02
NEXT_PUBLIC_STACK_DASHBOARD_URL=http://localhost:${NEXT_PUBLIC_STACK_PORT_PREFIX:-81}01
NEXT_PUBLIC_STACK_HOSTED_HANDLER_DOMAIN_SUFFIX=.localhost:${NEXT_PUBLIC_STACK_PORT_PREFIX:-81}09
NEXT_PUBLIC_STACK_API_URL=http://localhost:${NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX:-81}02
NEXT_PUBLIC_STACK_DASHBOARD_URL=http://localhost:${NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX:-81}01
NEXT_PUBLIC_STACK_HOSTED_HANDLER_DOMAIN_SUFFIX=.localhost:${NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX:-81}09
NEXT_PUBLIC_STACK_IS_LOCAL_EMULATOR=false
STACK_SERVER_SECRET=23-wuNpik0gIW4mruTz25rbIvhuuvZFrLOLtL7J4tyo

Expand All @@ -17,8 +17,8 @@ STACK_INTERNAL_PROJECT_PUBLISHABLE_CLIENT_KEY=this-publishable-client-key-is-for
STACK_INTERNAL_PROJECT_SECRET_SERVER_KEY=this-secret-server-key-is-for-local-development-only
STACK_SEED_INTERNAL_PROJECT_SUPER_SECRET_ADMIN_KEY=this-super-secret-admin-key-is-for-local-development-only

STACK_OAUTH_MOCK_URL=http://localhost:${NEXT_PUBLIC_STACK_PORT_PREFIX:-81}14
STACK_TURNSTILE_SITEVERIFY_URL=http://localhost:${NEXT_PUBLIC_STACK_PORT_PREFIX:-81}14/turnstile/siteverify
STACK_OAUTH_MOCK_URL=http://localhost:${NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX:-81}14
STACK_TURNSTILE_SITEVERIFY_URL=http://localhost:${NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX:-81}14/turnstile/siteverify

# Cloudflare Turnstile test keys — always-pass widgets, no real challenges
# See https://developers.cloudflare.com/turnstile/troubleshooting/testing/
Expand Down Expand Up @@ -49,12 +49,12 @@ STACK_ALLOW_SHARED_OAUTH_ACCESS_TOKENS=true
# apps/backend/src/lib/plan-entitlements.ts:arePlanLimitsEnforced.
STACK_DISABLE_PLAN_LIMITS=false

STACK_DATABASE_CONNECTION_STRING=postgres://postgres:PASSWORD-PLACEHOLDER--uqfEC1hmmv@localhost:${NEXT_PUBLIC_STACK_PORT_PREFIX:-81}28/stackframe
STACK_DATABASE_REPLICA_CONNECTION_STRING=postgres://postgres:PASSWORD-PLACEHOLDER--uqfEC1hmmv@localhost:${NEXT_PUBLIC_STACK_PORT_PREFIX:-81}34/stackframe
STACK_DATABASE_CONNECTION_STRING=postgres://postgres:PASSWORD-PLACEHOLDER--uqfEC1hmmv@localhost:${NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX:-81}28/stackframe
STACK_DATABASE_REPLICA_CONNECTION_STRING=postgres://postgres:PASSWORD-PLACEHOLDER--uqfEC1hmmv@localhost:${NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX:-81}34/stackframe
STACK_DATABASE_REPLICATION_WAIT_STRATEGY=pg-stat-replication

STACK_EMAIL_HOST=127.0.0.1
STACK_EMAIL_PORT=${NEXT_PUBLIC_STACK_PORT_PREFIX:-81}29
STACK_EMAIL_PORT=${NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX:-81}29
STACK_EMAIL_SECURE=false
STACK_EMAIL_USERNAME="does not matter, ignored by Inbucket"
STACK_EMAIL_PASSWORD="does not matter, ignored by Inbucket"
Expand All @@ -64,7 +64,7 @@ STACK_ACCESS_TOKEN_EXPIRATION_TIME=60s

STACK_DEFAULT_EMAIL_CAPACITY_PER_HOUR=100000

STACK_SVIX_SERVER_URL=http://localhost:${NEXT_PUBLIC_STACK_PORT_PREFIX:-81}13
STACK_SVIX_SERVER_URL=http://localhost:${NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX:-81}13
STACK_SVIX_API_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE2NTUxNDA2MzksImV4cCI6MTk3MDUwMDYzOSwibmJmIjoxNjU1MTQwNjM5LCJpc3MiOiJzdml4LXNlcnZlciIsInN1YiI6Im9yZ18yM3JiOFlkR3FNVDBxSXpwZ0d3ZFhmSGlyTXUifQ.En8w77ZJWbd0qrMlHHupHUB-4cx17RfzFykseg95SUk

# Trusted reverse proxy for reading real client IP addresses.
Expand All @@ -91,7 +91,7 @@ STACK_EMAIL_MONITOR_PROJECT_ID=internal
STACK_EMAIL_MONITOR_PUBLISHABLE_CLIENT_KEY=this-publishable-client-key-is-for-local-development-only
STACK_EMAIL_MONITOR_RESEND_EMAIL_DOMAIN=stack-generated.example.com
STACK_EMAIL_MONITOR_RESEND_EMAIL_API_KEY=this-is-a-fake-key
STACK_EMAIL_MONITOR_INBUCKET_API_URL=http://localhost:${NEXT_PUBLIC_STACK_PORT_PREFIX:-81}05
STACK_EMAIL_MONITOR_INBUCKET_API_URL=http://localhost:${NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX:-81}05
STACK_EMAIL_MONITOR_USE_INBUCKET=true
STACK_EMAIL_MONITOR_SECRET_TOKEN=this-secret-token-is-for-local-development-only

Expand All @@ -100,7 +100,7 @@ STACK_EMAILABLE_API_KEY=
STACK_INTERNAL_FEEDBACK_RECIPIENTS=team@stack-auth.com

# S3 Configuration for local development using s3mock
STACK_S3_ENDPOINT=http://localhost:${NEXT_PUBLIC_STACK_PORT_PREFIX:-81}21
STACK_S3_ENDPOINT=http://localhost:${NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX:-81}21
STACK_S3_REGION=us-east-1
STACK_S3_ACCESS_KEY_ID=s3mockroot
STACK_S3_SECRET_ACCESS_KEY=s3mockroot
Expand All @@ -109,23 +109,23 @@ STACK_S3_PRIVATE_BUCKET=stack-storage-private

# AWS region defaults to LocalStack
STACK_AWS_REGION=us-east-1
STACK_AWS_KMS_ENDPOINT=http://localhost:${NEXT_PUBLIC_STACK_PORT_PREFIX:-81}24
STACK_AWS_KMS_ENDPOINT=http://localhost:${NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX:-81}24
STACK_AWS_ACCESS_KEY_ID=test
STACK_AWS_SECRET_ACCESS_KEY=test

# Upstash defaults to one of the pre-build test users of the local emulator
STACK_QSTASH_URL=http://localhost:${NEXT_PUBLIC_STACK_PORT_PREFIX:-81}25
STACK_QSTASH_URL=http://localhost:${NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX:-81}25
STACK_QSTASH_TOKEN=eyJVc2VySUQiOiJkZWZhdWx0VXNlciIsIlBhc3N3b3JkIjoiZGVmYXVsdFBhc3N3b3JkIn0=
STACK_QSTASH_CURRENT_SIGNING_KEY=sig_7kYjw48mhY7kAjqNGcy6cr29RJ6r
STACK_QSTASH_NEXT_SIGNING_KEY=sig_5ZB6DVzB1wjE8S6rZ7eenA8Pdnhs

# MCP review tool (SpacetimeDB)
STACK_SPACETIMEDB_URI=ws://localhost:${NEXT_PUBLIC_STACK_PORT_PREFIX:-81}39
STACK_SPACETIMEDB_URI=ws://localhost:${NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX:-81}39
STACK_SPACETIMEDB_DB_NAME=stack-auth-llm
STACK_MCP_LOG_TOKEN=change-me

# Clickhouse
STACK_CLICKHOUSE_URL=http://localhost:${NEXT_PUBLIC_STACK_PORT_PREFIX:-81}36
STACK_CLICKHOUSE_URL=http://localhost:${NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX:-81}36
STACK_CLICKHOUSE_ADMIN_USER=stackframe
STACK_CLICKHOUSE_ADMIN_PASSWORD=PASSWORD-PLACEHOLDER--9gKyMxJeMx
STACK_CLICKHOUSE_EXTERNAL_PASSWORD=PASSWORD-PLACEHOLDER--EZeHscBMzE
Expand Down
8 changes: 4 additions & 4 deletions apps/backend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,14 @@
"with-env:dev": "dotenv -c development --",
"with-env:prod": "dotenv -c production --",
"with-env:test": "dotenv -c test --",
"dev": "BACKEND_PORT=${STACK_DEV_FALLBACK_BACKEND:+${NEXT_PUBLIC_STACK_PORT_PREFIX:-81}10} && BACKEND_PORT=${BACKEND_PORT:-${NEXT_PUBLIC_STACK_PORT_PREFIX:-81}02} && concurrently -n \"dev,codegen,prisma-studio,email-queue,cron-jobs,bulldozer-studio\" -k \"STACK_DISABLE_REACT_ASYNC_DEBUG_INFO=${STACK_DISABLE_REACT_ASYNC_DEBUG_INFO:-true} next dev --port $BACKEND_PORT ${STACK_BACKEND_DEV_EXTRA_ARGS:-}\" \"pnpm run codegen:watch\" \"pnpm run prisma-studio\" \"pnpm run run-email-queue\" \"pnpm run run-cron-jobs\" \"pnpm run run-bulldozer-studio\"",
"dev": "BACKEND_PORT=${STACK_DEV_FALLBACK_BACKEND:+${NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX:-81}10} && BACKEND_PORT=${BACKEND_PORT:-${NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX:-81}02} && concurrently -n \"dev,codegen,prisma-studio,email-queue,cron-jobs,bulldozer-studio\" -k \"STACK_DISABLE_REACT_ASYNC_DEBUG_INFO=${STACK_DISABLE_REACT_ASYNC_DEBUG_INFO:-true} next dev --port $BACKEND_PORT ${STACK_BACKEND_DEV_EXTRA_ARGS:-}\" \"pnpm run codegen:watch\" \"pnpm run prisma-studio\" \"pnpm run run-email-queue\" \"pnpm run run-cron-jobs\" \"pnpm run run-bulldozer-studio\"",
"dev:inspect": "STACK_BACKEND_DEV_EXTRA_ARGS=\"--inspect\" pnpm run dev",
"dev:profile": "STACK_BACKEND_DEV_EXTRA_ARGS=\"--experimental-cpu-prof\" pnpm run dev",
"build": "pnpm run codegen && next build",
"docker-build": "pnpm run codegen && next build --experimental-build-mode compile",
"build-self-host-migration-script": "tsdown --config scripts/db-migrations.tsdown.config.ts",
"analyze-bundle": "next experimental-analyze",
"start": "next start --port ${NEXT_PUBLIC_STACK_PORT_PREFIX:-81}02",
"start": "next start --port ${NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX:-81}02",
"codegen-prisma": "STACK_DATABASE_CONNECTION_STRING=\"${STACK_DATABASE_CONNECTION_STRING:-placeholder-database-connection-string}\" pnpm run prisma generate",
"codegen-prisma:watch": "STACK_DATABASE_CONNECTION_STRING=\"${STACK_DATABASE_CONNECTION_STRING:-placeholder-database-connection-string}\" pnpm run prisma generate --watch",
"generate-private-sign-up-risk-engine": "pnpm run with-env tsx scripts/generate-private-sign-up-risk-engine.ts",
Expand All @@ -28,9 +28,9 @@
"codegen": "pnpm run with-env pnpm run generate-migration-imports && pnpm run with-env bash -c 'if [ \"$STACK_ACCELERATE_ENABLED\" = \"true\" ]; then pnpm run prisma generate --no-engine; else pnpm run codegen-prisma; fi' && pnpm run generate-private-sign-up-risk-engine && pnpm run codegen-docs && pnpm run codegen-route-info",
"codegen:watch": "pnpm run generate-private-sign-up-risk-engine && concurrently -n \"prisma,private-risk-engine,docs,route-info,migration-imports\" -k \"pnpm run codegen-prisma:watch\" \"pnpm run generate-private-sign-up-risk-engine:watch\" \"pnpm run codegen-docs:watch\" \"pnpm run codegen-route-info:watch\" \"pnpm run generate-migration-imports:watch\"",
"psql-inner": "psql $(echo $STACK_DATABASE_CONNECTION_STRING | sed 's/\\?.*$//')",
"clickhouse": "pnpm run with-env clickhouse-client --host localhost --port ${NEXT_PUBLIC_STACK_PORT_PREFIX:-81}37 --user stackframe --password PASSWORD-PLACEHOLDER--9gKyMxJeMx",
"clickhouse": "pnpm run with-env clickhouse-client --host localhost --port ${NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX:-81}37 --user stackframe --password PASSWORD-PLACEHOLDER--9gKyMxJeMx",
"psql": "pnpm run with-env:dev pnpm run psql-inner",
"prisma-studio": "pnpm run with-env:dev prisma studio --port ${NEXT_PUBLIC_STACK_PORT_PREFIX:-81}06 --browser none",
"prisma-studio": "pnpm run with-env:dev prisma studio --port ${NEXT_PUBLIC_HEXCLAVE_PORT_PREFIX:-81}06 --browser none",
"prisma:dev": "pnpm run with-env:dev prisma",
"prisma": "pnpm run with-env prisma",
"db:migration-gen": "pnpm run with-env:dev tsx scripts/db-migrations.ts generate-migration-file",
Expand Down
6 changes: 3 additions & 3 deletions apps/backend/scripts/backfill-internal-free-plans.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import { ensureFreePlanForBillingTeam } from "@/lib/payments/ensure-free-plan";
// eslint-disable-next-line @typescript-eslint/no-deprecated -- idiomatic way to get the internal tenancy today (see plan-entitlements.ts)
import { DEFAULT_BRANCH_ID, getSoleTenancyFromProjectBranch, type Tenancy } from "@/lib/tenancies";
import { globalPrismaClient } from "@/prisma-client";
import { StackAssertionError } from "@stackframe/stack-shared/dist/utils/errors";
import { HexclaveAssertionError } from "@stackframe/stack-shared/dist/utils/errors";
import { getOrUndefined } from "@stackframe/stack-shared/dist/utils/objects";

// Page size for streaming teams. Big enough to amortise round-trips,
Expand Down Expand Up @@ -64,7 +64,7 @@ export async function runBackfillInternalFreePlans(): Promise<{
log("Starting...");
const internalTenancy = await getSoleTenancyFromProjectBranch("internal", DEFAULT_BRANCH_ID, true);
if (internalTenancy == null) {
throw new StackAssertionError("Internal billing tenancy not found", {
throw new HexclaveAssertionError("Internal billing tenancy not found", {
billingProjectId: "internal",
branchId: DEFAULT_BRANCH_ID,
});
Expand All @@ -79,7 +79,7 @@ export async function runBackfillInternalFreePlans(): Promise<{
|| freePlanProduct.customerType !== "team"
|| freePlanProduct.productLineId == null
) {
throw new StackAssertionError(
throw new HexclaveAssertionError(
"Internal tenancy `free` product is not configured as a team-typed, product-line-tagged plan; cannot run backfill",
{ freePlanProduct },
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import { getStripeForAccount } from "@/lib/stripe";
// eslint-disable-next-line @typescript-eslint/no-deprecated -- idiomatic way to get the internal tenancy today (see plan-entitlements.ts)
import { DEFAULT_BRANCH_ID, getSoleTenancyFromProjectBranch, type Tenancy } from "@/lib/tenancies";
import { getPrismaClientForTenancy, globalPrismaClient, retryTransaction } from "@/prisma-client";
import { StackAssertionError } from "@stackframe/stack-shared/dist/utils/errors";
import { HexclaveAssertionError } from "@stackframe/stack-shared/dist/utils/errors";
import { getOrUndefined } from "@stackframe/stack-shared/dist/utils/objects";
import type Stripe from "stripe";

Expand Down Expand Up @@ -136,7 +136,7 @@ export async function runRegenInternalSubscriptionsToLatest(options: {
log("Starting...");
const internalTenancy = await getSoleTenancyFromProjectBranch("internal", DEFAULT_BRANCH_ID, true);
if (internalTenancy == null) {
throw new StackAssertionError("Internal billing tenancy not found", {
throw new HexclaveAssertionError("Internal billing tenancy not found", {
billingProjectId: "internal",
branchId: DEFAULT_BRANCH_ID,
});
Expand Down Expand Up @@ -242,7 +242,7 @@ export async function regenSingleSubscription(args: {

const isStripeBacked = needsStripeMetadataRebase(sub);
if (isStripeBacked && stripe == null) {
throw new StackAssertionError(
throw new HexclaveAssertionError(
"regenSingleSubscription called for Stripe-backed sub without a stripe client",
{ subId: sub.id, stripeSubscriptionId: sub.stripeSubscriptionId, creationSource: sub.creationSource },
);
Expand Down
Loading
Loading