Multitenant

Errors

`MultitenantError` hierarchy and stable `code` values.

Every failure mode you should catch in integrator code extends MultitenantError and exposes a stable code string — use instanceof or switch (e.code), not fragile message substring checks.

Taxonomy

ClasscodeWhen
InvalidTenantsConfigErrorMULTITENANT_INVALID_CONFIGZod / cross-field validation, config merge conflicts, missing file, bad JSON
DomainResolutionErrorMULTITENANT_DOMAIN_RESOLUTIONAmbiguous domains at runtime, unknown environment, inconsistent market reference
TenantNotFoundErrorMULTITENANT_TENANT_NOT_FOUNDDomain points at missing tenant; requireTenant(); middleware onMissingTenant: 'throw' with no match

Helper: isMultitenantError(unknown) — type guard.

Config layer

validateTenantsConfig and loadTenantsConfig throw InvalidTenantsConfigError (not a generic Error).

Registry debugging

createTenantRegistry(config, { debug: true }) logs resolution steps to console.debug ( [multitenant] prefix ).

log: (msg, ...args) => void — plug in your logger (e.g. OpenTelemetry). No secrets logged; host, environment, matched tenantKey, basePath when set.

Adapter behaviour differences

Next.js App Router (@multitenant/next-app)

See Next.js — App Router. requireTenant() throws TenantNotFoundError when headers do not yield a tenant.

Next.js Pages (@multitenant/next-pages)

See Next.js — Pages Router.

APIWhen host does not resolve
withTenantApi404 JSON { error, code: 'MULTITENANT_TENANT_NOT_FOUND' }
withTenantGSSP{ notFound: true } — Next notFound(); no thrown TenantNotFoundError in GSSP itself

Express

onMissingTenant: 'throw' → pass TenantNotFoundError to next(err); pair with a middleware that uses isMultitenantError (see Express).

On this page