Open Closed

Tenant List Crashes with TypeError: Cannot read properties of undefined (reading 'pipe') #10714


User avatar
0
mohmmd.khalaf@gmail.com created

Environment Property Value ABP Commercial version 10.3.0 Package affected @volo/abp.ng.saas 10.3.0 Angular version 21.x (Vite/esbuild build pipeline) Browser Chromium-based (Chrome, Edge) API activationState response format String ("Active") Description Navigating to /saas/tenants crashes the Angular application with the following unhandled error:

TypeError: Cannot read properties of undefined (reading 'pipe') at _ExtensibleTableComponent.getContent (abp-ng.components-extensible.mjs:2929:35) at abp-ng.components-extensible.mjs:2894:26 at EntityPropList.forEach (abp-utils.js:259:13) at _ExtensibleTableComponent.prepareRecord (abp-ng.components-extensible.mjs:2888:19) The page does not render at all. The tenant list is completely inaccessible.

Root Cause Analysis The crash originates in DEFAULT_TENANTS_ENTITY_PROPS inside fesm2022/volo-abp.ng.saas.mjs. The activationState column's valueResolver function contains two bugs that each independently cause it to return undefined instead of an Observable. ExtensibleTableComponent.getContent() then calls .pipe() on that undefined, producing the crash.

Bug 1 — Unsafe destructuring of dateTimeFormat // Line ~603 in volo-abp.ng.saas.mjs const { shortDatePattern, shortTimePattern } = configState.getDeep('localization.currentCulture.dateTimeFormat'); configState.getDeep(...) returns undefined when the localization configuration has not fully loaded or the path does not resolve. Destructuring undefined throws a TypeError synchronously, causing the function to exit without returning a value — i.e., it returns undefined.

Bug 2 — switch compares against numeric enum values, but the API returns strings switch (data.record.activationState) { case TenantActivationState.Active: // = 0 return of(result); case TenantActivationState.ActiveWithLimitedTime: // = 1 return of(result); case TenantActivationState.Passive: // = 2 return of(result); // no default branch } The /api/saas/tenants API endpoint returns activationState as a string (e.g. "Active"), not a numeric enum value. None of the case branches match, the switch falls through, and the function implicitly returns undefined.

Both bugs result in getContent() receiving undefined and crashing on .pipe().

Steps to Reproduce Install ABP Commercial 10.3.0 Angular template. Create at least one tenant via the API or database. Navigate to Administration > Saas > Tenants. The page crashes immediately with the TypeError above. No tenant rows are rendered. Expected Behavior The tenant list renders correctly, showing each tenant with its activationState label (Active / Active With Limited Time / Passive).

Actual Behavior The page throws TypeError: Cannot read properties of undefined (reading 'pipe') and renders nothing.

Workaround Until an official fix is released, the crash can be suppressed by overriding the broken EntityProp via the ABP Angular extensibility contributor API.

src/app/shared/saas-entity-prop-contributors.ts — define a safe replacement valueResolver that:

Wraps the dateTimeFormat access in a try/catch / || {} fallback. Handles both string ("Active") and numeric (0) values of activationState. Always returns an Observable (never undefined). Register it via SAAS_ENTITY_PROP_CONTRIBUTORS in app.config.ts providers.

Suggested Fix In DEFAULT_TENANTS_ENTITY_PROPS (fesm2022/volo-abp.ng.saas.mjs):

  1. Guard the dateTimeFormat destructuring:

// Before const { shortDatePattern, shortTimePattern } = configState.getDeep('localization.currentCulture.dateTimeFormat');

// After const { shortDatePattern, shortTimePattern } = configState.getDeep('localization.currentCulture.dateTimeFormat') || {}; 2. Replace the switch with if/else and handle both string and numeric enum values:

// Before switch (data.record.activationState) { case TenantActivationState.Active: return of(result); case TenantActivationState.ActiveWithLimitedTime: return of(result); case TenantActivationState.Passive: return of(result); // no default — returns undefined for string values like "Active" }

// After const state = data.record.activationState; if (state === TenantActivationState.Active || state === 'Active') { // build result for Active } else if (state === TenantActivationState.ActiveWithLimitedTime || state === 'ActiveWithLimitedTime') { // build result for ActiveWithLimitedTime } else if (state === TenantActivationState.Passive || state === 'Passive') { // build result for Passive } else { return of(''); } return of(result); 3. Wrap the entire valueResolver body in a try/catch:

valueResolver: data => { try { // ... existing logic with guards above applied ... return of(result); } catch { return of(''); } } References node_modules/@volo/abp.ng.saas/fesm2022/volo-abp.ng.saas.mjs — DEFAULT_TENANTS_ENTITY_PROPS, activationState prop, valueResolver function node_modules/@abp/ng.components/fesm2022/abp-ng.components-extensible.mjs:2929 — ExtensibleTableComponent.getContent() ABP Angular Extensibility docs: https://abp.io/docs/latest/framework/ui/angular/entity-prop-extensions

Markdown supported.
Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)

1 Answer(s)
  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    Hi,

    By default ABP returns enums as numbers, not strings. We reproduced on a fresh ABP 10.3 Angular tiered project and /api/saas/tenants returned:

    "activationState": 0
    

    Not "Active". With this default response, the tenants page renders normally.

    In your environment it returns "Active", which means something in your backend is overriding the default JSON behavior. The most common cause is a custom JsonStringEnumConverter registered somewhere — AddJsonOptions, Configure<JsonOptions> in your *.HttpApi.Host, or pulled in by a third-party module.

    Could you share:

    1. Any custom JSON / serializer configuration in your backend — AddJsonOptions, Configure<JsonOptions>, JsonStringEnumConverter, Newtonsoft replacement, etc.
    2. A raw response of GET /api/saas/tenants?skipCount=0&maxResultCount=10 from your environment.

    Removing the custom JSON configuration and letting ABP return enums as numbers should resolve the page crash without any other change.

    Thanks

    Markdown supported.
    Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)
Boost Your Development
ABP Live Training
Packages
See Trainings
Mastering ABP Framework Book
The Official Guide
Mastering
ABP Framework
Learn More
Mastering ABP Framework Book
Made with ❤️ on ABP v10.8.0-preview. Updated on October 05, 2026, 11:32
1
ABP Assistant
🔐 You need to be logged in to use the chatbot. Please log in first.