For license errors like ABP-LIC-0017 that start after the application has already been running for some time, the root cause is almost always related to the actual Commercial license record (expiration, limits, changes on the license, key regeneration, etc.), not to your project code.
Since this is directly related to your commercial license status, it must be checked on ABP’s side (we can’t see or validate your license from here).
Please do the following:
ABP-LIC-0017 and Volo.Abp.AuditLogging.HttpApi-v9.2.0.0 messages.After they respond, replace the existing license key/file in your project with the one they provide and restart the application.
For license and commercial issues, please contact ABP directly:
This response was generated by AI. If it didn’t solve your problem, feel free to post a new answer — our support team will jump in to help you soon.
Make sure you installed the Apple Silicon build
macOS Apple Silicon (M1/M2/M3)macOS IntelRun ABP Studio from Terminal to see the error This usually shows exactly why it is not starting.
# Close ABP Studio if it's running / stuck
pkill "ABP Studio" 2>/dev/null
# Run it manually
"/Applications/ABP Studio.app/Contents/MacOS/ABP Studio"
Check ABP Studio logs on macOS ABP Studio writes its own logs under your home folder. On macOS they are typically here:
ls ~/.abp/studio/ui/logs
ls ~/.abp/studio/backend/logs
Open the latest .log file from each folder and look for ERROR lines around the time you tried to start Studio.
# Close Studio first
pkill "ABP Studio" 2>/dev/null
# Backup and remove Studio data
mv ~/.abp/studio ~/.abp/studio-backup-$(date +%s)
# Then reinstall ABP Studio (Apple Silicon build) and run it again
~/.abp/studio/.../logsThese steps are the standard way we diagnose “ABP Studio starts and immediately closes / doesn’t open” issues on macOS Apple Silicon.
This response was generated by AI. If it didn’t solve your problem, feel free to post a new answer — our support team will jump in to help you soon.
License validation (including checking whether your license is valid/active and whether it covers ABP Commercial 9.2.0) can only be done by the ABP team against your actual license data; it cannot be reliably diagnosed from application logs alone.
For ABP-LIC-0017 and the "License check failed for 'Volo.Abp.AuditLogging.HttpApi-v9.2.0.0'" error, please contact the ABP team directly so they can:
You should share with them:
They will validate the license and provide a corrected license file or further steps.
This response was generated by AI. If it didn’t solve your problem, feel free to post a new answer — our support team will jump in to help you soon.
The situation you see is consistent with “user has been signed‑out during the request”:
application-configuration item in cache has a key that contains the userId (this entry was created earlier, when the user was still authenticated).IntrospectAccessToken / your modified CheckTokenExpiration logic runs, the cookie is rejected and the user is signed out.application-configuration request that comes after that, the current HTTP context no longer has an authenticated principal, so:
ICurrentUser returns IsAuthenticated = false and Id = null."auth": { "grantedPolicies": {} }.userId = null).So:
currentUser all null + empty grantedPolicies means the user is no longer authenticated for that request.If you want to make the behavior clearer/safer:
CheckTokenExpiration/IntrospectAccessToken copy) signs the user out before the application‑configuration endpoint runs (which it already appears to do).This response was generated by AI. If it didn’t solve your problem, feel free to post a new answer — our support team will jump in to help you soon.
The GetContextManyAsync second result shows an error "fetch failed", but we still got some context chunks; nothing about Africa/Asmera. Need to search code repo for TimeZoneHelper and version 10 changes, and maybe TimeZoneConverter usage. Next: use list_repos result to know repo id for abpframework, then search_code for TimeZoneHelper and Africa/Asmera. Repo listing failed (auth). But I must still call search_code per instructions; without repoId it'll search all.
This response was generated by AI. If it didn’t solve your problem, feel free to post a new answer — our support team will jump in to help you soon.
Below is a concrete, “safe” way to get rid of the duplicate-@angular/core problem and align your project with what ABP 10 expects.
ABP v10.0 Angular UI is designed to run on Angular 20:
10.0.2) is the version line that officially targets Angular 20.So, for Angular 20 you should be on:
"@abp/ng.core": "10.0.2",
"@abp/ng.components": "10.0.2",
"@abp/ng.theme.shared": "10.0.2",
...
"@angular/*": "20.0.7" // or ~20.0.7
(versions shown as example – key point is all ABP Angular packages in the 10.x line and all @angular/* on a single 20.0.x version).
@abp/ng.theme.shared@10.0.2 expected to work with Angular 20?Yes.
@abp/ng.theme.shared@10.0.2 belongs to the ABP 10.0 Angular UI stack, which is built for Angular 20.@swimlane/ngx-datatable@21.1.0 (17.x || 18.x || 19.x) are expected when you move to Angular 20 and do not, by themselves, break the build.So from ABP’s side, @abp/ng.theme.shared@10.0.2 + Angular 20 is a valid combination.
The blocking errors you pasted:
TS2451: Cannot redeclare block-scoped variable 'ngI18nClosureMode'.
node_modules/angular-oauth2-oidc/node_modules/@angular/core/...d.ts
node_modules/@angular/core/...d.ts
TS2451: Cannot redeclare block-scoped variable 'ngDevMode'.
node_modules/angular-oauth2-oidc/node_modules/@angular/core/...d.ts
node_modules/@angular/core/...d.ts
show that a second copy of @angular/core was installed under:
node_modules/angular-oauth2-oidc/node_modules/@angular/core
This is a general Node/Angular dependency resolution issue (not specific to ABP), typically caused by:
@angular/* packages or libraries that depend on them.yarn.lock / package-lock.json) created with older ranges, causing npm/yarn to resolve a nested @angular/core inside a dependency such as angular-oauth2-oidc.This is not caused directly by ngx-datatable. The peer warning from ngx-datatable is mostly cosmetic in this context; the real build break is the nested @angular/core.
Make sure all your Angular & ABP Angular packages are on a single, consistent set of versions, without any ^ ranges that could drift:
Example (you can adapt the exact patch version to yours, like 20.0.7):
{
"dependencies": {
"@angular/animations": "~20.0.7",
"@angular/common": "~20.0.7",
"@angular/compiler": "~20.0.7",
"@angular/core": "~20.0.7",
"@angular/forms": "~20.0.7",
"@angular/localize": "~20.0.7",
"@angular/platform-browser": "~20.0.7",
"@angular/platform-browser-dynamic": "~20.0.7",
"@angular/router": "~20.0.7",
"@abp/ng.core": "10.0.2",
"@abp/ng.components": "10.0.2",
"@abp/ng.oauth": "10.0.2",
"@abp/ng.theme.shared": "10.0.2",
// ...other @abp/* and @volo/* at 10.0.2-compatible versions
// Keep other libs, but avoid pinning their own @angular/* versions
},
"devDependencies": {
"@angular-devkit/build-angular": "~20.0.x",
"@angular/cli": "~20.0.x",
"@angular/compiler-cli": "~20.0.x",
"@angular/language-service": "~20.0.x",
// ...
}
}
Key points:
~ for @angular/* and exact (or ~10.0.2) for ABP packages, like ABP support examples do for other Angular versions.package.json that independently pulls in another @angular/core version.After normalizing versions:
node_modulesyarn.lock or package-lock.json)# if you use yarn
yarn install
# or npm
npm install
@angular/core:npm ls @angular/core
# or
yarn why @angular/core
You must see only the root @angular/core@20.0.7 and no nested copy such as angular-oauth2-oidc/node_modules/@angular/core.
If you still see a nested @angular/core under any package, that package’s peer range conflicts strongly enough that npm/yarn is installing its own copy. In that case:
angular-oauth2-oidc).resolutions/overrides block (Yarn / npm v8+) to force a single Angular version:{
"overrides": {
"@angular/core": "20.0.7",
"@angular/common": "20.0.7",
"@angular/platform-browser": "20.0.7",
"@angular/platform-browser-dynamic": "20.0.7"
}
}
Then delete lockfile + node_modules and reinstall again.
In ABP support tickets for earlier versions, very similar “dependency normalization” (pinning all
@angular/*,@abp/*,@volo/*to consistent~ranges and reinstalling) is exactly how build/startup issues were resolved.
@swimlane/ngx-datatable specifically?@swimlane/ngx-datatable@21.1.0 is pulled in transitively by @abp/ng.theme.shared.17.x || 18.x || 19.x) is conservative; Angular 20 is newer, so npm/yarn warns.angular-oauth2-oidc (or another library) installing its own @angular/core.So, you do not need to replace ngx-datatable just to get Angular 20 working. Focus on ensuring there is only one @angular/core in the tree as described above.
If you want to be very strict in CI (treating warnings as errors), you can:
ngx-datatable usage in your own code with another grid solution and remove it from your direct dependencies. But ABP’s theme will still bring it transitively until ABP replaces it in a future version; there is no official statement yet that it has been fully removed.abp update (CLI), orpackage.json @angular/* and @abp/* versions match what a fresh ABP 10 Angular template would generate (this is the safest way to avoid hidden version drift).node_modules + lock file, reinstall.npm ls @angular/core
shows a single 20.0.x install. 6. Re-run:
ng build --configuration production
in CI and locally.
This aligns your project with ABP’s official Angular 20 setup and eliminates the duplicate-core TS2451 errors.
ABP 10.0 Migration Guide (includes .NET 10 and Angular 20 template changes):
https://abp.io/docs/10.0/release-info/migration-guides/abp-10-0
ABP 10.0 RC Announcement (details Angular 20 / new esbuild-based builder and SSR for Angular UI):
https://abp.io/community/announcements/announcing-abp-10-0-release-candidate-86lrnyox
Angular UI Migration v2.9 → v3 (older, but shows ABP’s pattern of tightly coupling a specific Angular major to an ABP major):
https://abp.io/docs/latest/framework/ui/angular/migration-guide-v3
This response was generated by AI. If it didn’t solve your problem, feel free to post a new answer — our support team will jump in to help you soon.
The CORE_OPTIONS error is not caused by your tsconfig.json anymore (your paths look correct). In ABP Angular, this error is almost always due to version mismatches or an extra CoreModule.forRoot/import. Below is a concrete checklist that fixes the issue in 9.x projects.
package.json, make sure all of these have the same minor version line:@abp/ng.* → ~9.2.4@volo/abp.ng.* → ~9.2.4@volosoft/abp.ng.theme.lepton-x → ~4.2.4 (this is correct for ABP 9.2.x)@volo/ngx-lepton-x.core → ~4.2.4@angular/* → all the same major/minor (one line, e.g. all ~18.x.x or all ~19.x.x – but all must be identical)Make sure there is no different version of any of these packages pulled in indirectly; if you see any other version ranges (like ^9.1.x or ~9.0.x) for @abp, @volo or @volosoft in dependencies or devDependencies, change them to ~9.2.4 to match.
In a very similar support case, the exact same
CORE_OPTIONSerror disappeared as soon as all@abp/*,@volo/*and the theme package were normalized to the same minor version.
package.json, fully clear and reinstall:# in the Angular project folder
rm -rf node_modules .angular yarn.lock package-lock.json
yarn cache clean || npm cache clean --force
yarn # or npm install
yarn start # or npm start
CoreModule is imported only once with forRootCheck all your Angular modules for @abp/ng.core imports.
AppModule (root), it must be:CoreModule.forRoot({
environment,
registerLocaleFn: registerLocale(),
}),
forRoot. If you import CoreModule there, it should be without forRoot:// ✅ allowed in feature/shared modules
import { CoreModule } from '@abp/ng.core';
@NgModule({
imports: [
CoreModule, // WITHOUT .forRoot()
// ...
],
})
export class SomeFeatureModule {}
If you have any other CoreModule.forRoot(...) in the project (including inside your own libraries), Angular will create a separate injector that does not get the CORE_OPTIONS from your main AppModule, and RestService (from @abp/ng.core) will fail with exactly the error you see.
So:
CoreModule.forRoot and keep it only in AppModule.CoreModule.The support context for this error also shows it happens when a project:
tsconfig paths pointing to those local copies.You already set:
"paths": {
"@abp/*": ["node_modules/@abp/*"],
"@volo/*": ["node_modules/@volo/*"],
"@proxy": [ "src/app/proxy/index.ts" ],
"@proxy/*": [ "src/app/proxy/*" ]
}
Now verify that:
tsconfig*.json files (in libs/projects) that override @abp/* or @volo/* to some local folder.paths.If you find any path like "@volo/abp.ng.identity": ["projects/identity/src/public-api.ts"] etc., remove those mappings (or rename your custom libs to a different prefix) so @abp/* and @volo/* always resolve to node_modules.
This is usually resolved automatically once CoreModule.forRoot + registerLocaleFn run from the correct @volo/abp.ng.language-management version, but verify:
registerLocale exactly like this (which you already do):import { registerLocale } from '@volo/abp.ng.language-management/locale';
CoreModule.forRoot({
environment,
registerLocaleFn: registerLocale(),
}),
Your angular.json (or workspace config) app’s assets section should include ABP localization assets (in a 9.x Angular app this is done by the template). Make sure these lines (or their equivalent) exist for your main app:
"assets": [
"src/favicon.ico",
"src/assets",
{
"glob": "**/*",
"input": "node_modules/@abp/ng.theme.shared/assets",
"output": "/assets"
}
]
There needs to be an en locale JSON under /assets (e.g. /assets/abp-localization/en.json or similar). If the assets from @abp/ng.theme.shared are not copied, you get the “Cannot find the en locale file” error.
Rebuild after any change to angular.json:
yarn start --configuration development # or just yarn start (depending on your setup)
Once the versions are normalized, CoreModule.forRoot is only in AppModule, and localization assets are in place, both:
NullInjectorError: No provider for InjectionToken CORE_OPTIONS!Cannot find the en locale file.should be resolved on a clean build.
This response was generated by AI. If it didn’t solve your problem, feel free to post a new answer — our support team will jump in to help you soon.
The NullInjectorError: No provider for InjectionToken CORE_OPTIONS! and the “Cannot find the en locale file” error are both symptoms of the same root cause: Angular is not resolving the correct @abp/* / @volo/* packages (so the DI configuration from @abp/ng.core is never applied, and the locale files can’t be found).
This exact issue is known on ABP 9.x Angular (see Microservice template case) and is fixed by normalizing the TypeScript paths so they point to node_modules.
Do the following in your Angular app (the one that contains app.module.ts you shared):
Edit tsconfig.json of the Angular app (usually apps/angular/tsconfig.json in microservice templates, or root tsconfig.json in single app):
Add/merge these paths under compilerOptions:
{
"compilerOptions": {
// ...existing options...
"paths": {
// keep your existing paths, then add/override these:
"@abp/*": ["node_modules/@abp/*"],
"@volo/*": ["node_modules/@volo/*"]
}
}
}
@abp/* or @volo/* entries, make sure they only point to node_modules/@abp/* and node_modules/@volo/*, not to any local libs.Clean and reinstall dependencies
From the Angular project folder:
rm -rf node_modules
rm -f package-lock.json yarn.lock
# then
yarn # or npm install
yarn start # or npm start
Verify your root module setup
Your AppModule’s core setup is already correct for ABP 9.2.x:
CoreModule.forRoot({
environment,
registerLocaleFn: registerLocale(),
}),
Once @abp/ng.core is correctly resolved from node_modules, this will:
CORE_OPTIONS (fixing the NullInjectorError).en locale (fixing “Cannot find the en locale file”).After applying the paths fix and reinstalling dependencies, both errors should disappear on a fresh build.
This response was generated by AI. If it didn’t solve your problem, feel free to post a new answer — our support team will jump in to help you soon.
CheckTokenExpiration() and IntrospectAccessToken() are just two different ABP helpers that plug into the cookie authentication pipeline:
IntrospectAccessToken() (obsolete)
ControlCenter (or some other client/resource).APP‑2 introspects it with its own ClientId, OpenIddict sees that this ClientId is not in aud/azp and rejects the request:
The introspection request was rejected because the access token was issued to a different client or for another resource server.active: false even when the token itself is valid.CheckTokenExpiration() (new, recommended)
Because you have many apps (Portal, APP‑1/2/3) with SSO and different OpenIddict clients, IntrospectAccessToken() will always be fragile unless all access tokens are issued with all your frontend ClientIds as audiences.
The workaround suggested in the support thread is:
options.IntrospectAccessToken() from all apps.CookieAuthenticationOptionsExtensions.cshttps://github.com/abpframework/abp/blob/dev/framework/src/Volo.Abp.AspNetCore/Microsoft/Extensions/DependencyInjection/CookieAuthenticationOptionsExtensions.csCheckTokenExpiration/validation logic, change the ClientId used for introspection:
ClientId, take the ClientId (or audience) from the access token being validated, or use a single technical client that is always present in aud.ValidateIntrospectionRequest handler.If you do this:
IntrospectAccessToken (user is redirected to login when token is invalid/expired).Regarding your last comment:
Using
CheckTokenExpirationlets users access internal URLs without logging in, butIntrospectAccessTokendoes not.
That difference comes from the exact validation logic inside the ABP extension. Once you copy the extension code and adapt the introspection part (ClientId/audience logic) you can:
ApplicationName, Redis Protection-Keys shared) architecture.CookieAuthenticationOptionsExtensionsThis response was generated by AI. If it didn’t solve your problem, feel free to post a new answer — our support team will jump in to help you soon.
Your expectation is reasonable, but with ABP 9.3.x what you want is not supported by the Angular proxy generator.
More precisely:
IRemoteStreamContent itself is supported by:
However, the Angular proxy generator only switches to FormData when:
IRemoteStreamContent / RemoteStreamContent, orIEnumerable<IRemoteStreamContent>) is a top-level parameter.It does not inspect complex DTO graphs like:
public class TestUploadInput
{
public Guid RecordId { get; set; }
public TestUploadInputDocument[] Documents { get; set; } = [];
}
public class TestUploadInputDocument
{
public Guid DocumentId { get; set; }
public IEnumerable<IRemoteStreamContent> Files { get; set; } = [];
}
public void Upload([FromForm] TestUploadInput input) ...
and therefore always generates JSON (or query params) for TestUploadInput, not FormData.
There is no configuration switch in 9.3 to tell the Angular proxy generator “for this DTO, use FormData”.
So what you see:
uploadByInput = (input: TestUploadInput, ...) =>
this.restService.request<any, void>({
method: 'POST',
url: '/api/app/ownership-change-flow/upload',
body: input, // or params: { ... }
}, ...);
is exactly the current limitation, not a misconfiguration on your side.
Given that, the only fully working approaches in 9.3.6 are:
You can continue to use your DTO structure exactly as-is on the backend, and just bypass the generated proxy for this method only.
public class OwnershipChangeFlowAppService : ApplicationService
{
public void Upload([FromForm] TestUploadInput input)
{
// input.RecordId
// input.Documents[i].DocumentId
// input.Documents[i].Files (IEnumerable<IRemoteStreamContent>)
}
}
(And ensure you configure MVC so this DTO isn’t JSON-bound, e.g. with FormBodyBindingIgnoredTypes if needed, as described in the docs.)
RestService that sends the FormData the way the backend expects:import { Injectable } from '@angular/core';
import { RestService } from '@abp/ng.core';
@Injectable({ providedIn: 'root' })
export class OwnershipChangeFlowUploadClient {
constructor(private restService: RestService) {}
upload(input: {
recordId: string;
documents: { documentId: string; files: File[] }[];
}) {
const form = new FormData();
form.append('recordId', input.recordId);
input.documents.forEach((doc, docIndex) => {
form.append(`documents[${docIndex}].documentId`, doc.documentId);
doc.files.forEach(file => {
// Name must match DTO structure that ASP.NET Core can bind to.
form.append(`documents[${docIndex}].files`, file);
});
});
return this.restService.request<any, void>(
{
method: 'POST',
url: '/api/app/ownership-change-flow/upload',
body: form,
},
{ apiName: 'Default' },
);
}
}
ABP support has already confirmed in a previous ticket that for such file upload scenarios you should not use the generated Angular proxy when it does not produce FormData, and instead send FormData manually with RestService/HttpClient.
FormDataIf you want to rely strictly on the generated Angular proxy, you must change your method into a shape the generator understands, e.g. flattening out the file parameters so they are top-level IRemoteStreamContent / IEnumerable<IRemoteStreamContent> and using a simpler DTO for the rest of the data.
For example (conceptually):
public class TestUploadFlatInput
{
public Guid RecordId { get; set; }
public Guid[] DocumentIds { get; set; } = [];
}
public Task UploadAsync(
[FromForm] TestUploadFlatInput input,
IEnumerable<IRemoteStreamContent> files)
{
// correlate input.DocumentIds[i] with files.ElementAt(i) yourself
}
For such signatures the Angular proxy generator can generate a method that takes FormData as body. But with nested IRemoteStreamContent inside DTOs/child DTOs, it cannot.
I believe it should be possible to generate a function which accepts
FormDatainstead…
From a design perspective: yes, it could be implemented in the generator.
In ABP 9.3.6 however, this is not implemented, and there is no extension point to change the Angular proxy generator’s behavior for this specific method or DTO.
So currently:
IRemoteStreamContent is valid and supported on the server side.FormData client for that method (A), orIf this is blocking and you want first-class generator support for nested DTO uploads, the next step would be to open an issue on ABP’s GitHub repo or via the ABP support portal so the team can treat it as a feature/bug for a future version.
Working with Streams (IRemoteStreamContent, DTO + FormBodyBindingIgnoredTypes):
https://abp.io/docs/9.3/framework/architecture/domain-driven-design/application-services#working-with-streams
ABP support ticket where the team recommends not using the generated Angular proxy for file uploads and instead sending FormData manually:
https://abp.io/support/questions/5731
This response was generated by AI. If it didn’t solve your problem, feel free to post a new answer — our support team will jump in to help you soon.