Skip to content

Error: schema with key or id "BuilderProgressSchema" already exists #20847

Closed
@bgotink

Description

@bgotink

🐞 Bug report

Command (mark with an x)

  • new
  • build
  • serve
  • test
  • e2e
  • generate
  • add
  • update
  • lint
  • extract-i18n
  • run
  • config
  • help
  • version
  • doc

Is this a regression?

Yes, this didn't cause issues when using angular 11.

Description

Any builder that ends up using multiple instances of @angular-devkit/architect results in an error.

Example scenario: package 1 exposes a builder that executes a builder in package 2, both packages have their own copy of @angular-devkit/architect in node_modules, e.g. because of deviating versions or because the package manager doesn't hoist the dependency.

🔬 Minimal Reproduction

Clone https://github.com/bgotink/ngx-playwright/tree/repro-angular-schema-error and try to build

$ cd $(mktemp -d)
$ git clone --depth 1 https://github.com/bgotink/ngx-playwright --single-branch -b repro-angular-schema-error .
$ yarn
$ yarn ng build all

The last command uses a builder from one package to run multiple builders from another package. Both of these packages have an identical copy of @angular-devkit/architect version 0.1200.0-rc.2 while the node_modules folder itself contains @angular-devkit/architect version 0.1200.0.

Building works fine if the situation is identical but using angular 11 packages.
Building also works fine if I add a resolution to force only a single (hoisted) version of @angular-devkit/architect to be installed.

🔥 Exception or Error

/.../node_modules/rxjs/internal/util/hostReportError.js:4
    setTimeout(function () { throw err; }, 0);
                             ^

Error: schema with key or id "BuilderProgressSchema" already exists
    at Ajv._checkUnique (/.../node_modules/@angular-devkit/core/node_modules/ajv/dist/core.js:448:19)
    at Ajv._addSchema (/.../node_modules/@angular-devkit/core/node_modules/ajv/dist/core.js:439:22)
    at Ajv.runCompileAsync (/.../node_modules/@angular-devkit/core/node_modules/ajv/dist/core.js:156:30)
    at async CoreSchemaRegistry._compile (/.../node_modules/@angular-devkit/core/src/json/schema/registry.js:215:25)

I've logged the ids of compiled schemas before and after compilation and noticed that two copies of the BuilderProgressSchema schema are being compiled at the same time.
This didn't give rise to issues in angular 11 because the CoreSchemaRegistry first tried to compile the schemas synchronously, which works for these schemas. In angular 12, the compilation is always asynchronous, which means multiple schemas can end up being compiled at the same time. This breaks as ajv only supports compiling one schema any given id. The relevant part of CoreSchemaRegistry#_compile function boils down to

ajv.remove(schema);

// actual compilation happens no earlier than the next microtick thanks to an await in the ajv functions
await ajv.compileAsync(schema);

which ends up removing the schema twice and then compiling it twice, causing the error above.

🌍 Your Environment


     _                      _                 ____ _     ___
    / \   _ __   __ _ _   _| | __ _ _ __     / ___| |   |_ _|
   / △ \ | '_ \ / _` | | | | |/ _` | '__|   | |   | |    | |
  / ___ \| | | | (_| | |_| | | (_| | |      | |___| |___ | |
 /_/   \_\_| |_|\__, |\__,_|_|\__,_|_|       \____|_____|___|
                |___/
    

Angular CLI: 12.0.0
Node: 14.15.3
Package Manager: yarn 2.4.1
OS: darwin x64

Angular: undefined
... 

Package                      Version
------------------------------------------------------
@angular-devkit/architect    0.1200.0
@angular-devkit/core         12.0.0
@angular-devkit/schematics   12.0.0-rc.2
@angular/cli                 12.0.0
@schematics/angular          12.0.0
typescript                   4.2.4

Anything else relevant?

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions