# Au 2.0: Downstream error after resolving a factory with a string

**URL:** <https://discourse.aurelia.io/t/au-2-0-downstream-error-after-resolving-a-factory-with-a-string/6557>\
**Category:** Framework Knowledge\
**Created:** [December 23, 2025, 5:53am UTC](https://discourse.aurelia.io/t/au-2-0-downstream-error-after-resolving-a-factory-with-a-string/6557 "2025-12-23T05:53:40Z")\
**Posts on this page:** 16\
**Page:** 1

<div class="post-metadata">

**Author:** ![estaylorco](https://yyz1.discourse-cdn.com/flex027/user_avatar/discourse.aurelia.io/estaylorco/32/1887_2.png) [@estaylorco](https://discourse.aurelia.io/u/estaylorco)\
**Post date:** [December 23, 2025, 5:53am UTC](https://discourse.aurelia.io/t/au-2-0-downstream-error-after-resolving-a-factory-with-a-string/6557/1 "2025-12-23T05:53:40Z")

</div>

Hello,

**Is it permitted to use strings when resolving a factory?**

When I do this, I don’t get an error, at least not at this point, but I do downstream:

```javascript
this.documentFactory = resolve(factory('ItbDocumentFactory'));

```

My registration in **main.js** is this:

```javascript
Registration.transient('ItbDocumentFactory', ItbDocumentFactory),

```

I then use the factory like this (at the moment, I’m not passing arguments, just to test by slowly building up):

```javascript
const doc = this.documentFactory();

```

This is the error caused by the line above:

 ![Screenshot 2025-12-22 at 10.44.19 PM](https://canada1.discourse-cdn.com/flex027/uploads/aurelia/original/2X/7/723ff014e3f573671ae9ed1bc52e4056cf1f3420.png)

When I resolve using the actual service, not a string, I don’t get the error. This is fine downstream:

```javascript
this.documentFactory = resolve(factory(ItbDocumentFactory));

```

---

<div class="post-metadata">

**Author:** ![bigopon](https://yyz1.discourse-cdn.com/flex027/user_avatar/discourse.aurelia.io/bigopon/32/18_2.png) [@bigopon](https://discourse.aurelia.io/u/bigopon)\
**Post date:** [December 23, 2025, 11:12am UTC](https://discourse.aurelia.io/t/au-2-0-downstream-error-after-resolving-a-factory-with-a-string/6557/2 "2025-12-23T11:12:46Z")

</div>

The `factory` resolver creates a resolver to lazily construct instances of a constructable function (/class). It’s not a resolver to retrieve your registration in this case.

If you want to follow with the pattern described here, you’ll need to do something like this

```typescript
this.documentFactory = resolve('ItbDocumentFactory') as ItbDocumentFactory;

```

`ItbDocumentFactory` is already a factory. Unless the actual code of it tells a completely different story.

---

<div class="post-metadata">

**Author:** ![estaylorco](https://yyz1.discourse-cdn.com/flex027/user_avatar/discourse.aurelia.io/estaylorco/32/1887_2.png) [@estaylorco](https://discourse.aurelia.io/u/estaylorco)\
**Post date:** [December 23, 2025, 4:55pm UTC](https://discourse.aurelia.io/t/au-2-0-downstream-error-after-resolving-a-factory-with-a-string/6557/3 "2025-12-23T16:55:38Z")

</div>

_(Please note that I do not, as of yet, use ts, only js)._

Sorry about that @bigopon . I had created a separate project in preparation for a repro, and I didn’t keep it up to the minute as I was wrestling with this in my main project. I understand why the naming conventions threw you. I just got into the office, and updated the isolated project.

**Nevertheless, the problem persists.** I use `Factory.of` all over the place in my Au 1.0 app (the one I’m migrating). I’m the one who posted this over 4 years ago ( [Will Factory.of() be supported in Aurelia 2?](https://discourse.aurelia.io/t/will-factory-of-be-supported-in-aurelia-2/4282) )🙂 !

I should have written this in the post:

```javascript
...
Registration.transient('ItbDocument', ItbDocument)
...

```

and where the factory is resolved:

```javascript
this.documentFactory = resolve(factory('ItbDocument'));

```

and where the factory is used:

```javascript
this.document = this.documentFactory();

```

---

<div class="post-metadata">

**Author:** ![bigopon](https://yyz1.discourse-cdn.com/flex027/user_avatar/discourse.aurelia.io/bigopon/32/18_2.png) [@bigopon](https://discourse.aurelia.io/u/bigopon)\
**Post date:** [December 24, 2025, 12:00am UTC](https://discourse.aurelia.io/t/au-2-0-downstream-error-after-resolving-a-factory-with-a-string/6557/4 "2025-12-24T00:00:04Z")

</div>

ahh, that seems to be a missing capability of the current implementation. If it works in v1 then we probably should support it in v2. Currently factory resolution only understands constructables, not a key that resolves to a constructable. Maybe let’s track this with a bug report as well?

---

<div class="post-metadata">

**Author:** ![estaylorco](https://yyz1.discourse-cdn.com/flex027/user_avatar/discourse.aurelia.io/estaylorco/32/1887_2.png) [@estaylorco](https://discourse.aurelia.io/u/estaylorco)\
**Post date:** [December 24, 2025, 12:50am UTC](https://discourse.aurelia.io/t/au-2-0-downstream-error-after-resolving-a-factory-with-a-string/6557/5 "2025-12-24T00:50:47Z")

</div>

@bigopon You know, I don’t know if I ever could register with a string in Au 1.0. **So I don’t want to mislead here**.

It just seemed natural based on what you guys have done.

In migrating to 2.0, I’m taking advantage of the opportunity to improve my tabbed viewer. My tabbed viewer stores durable session data in jsonb columns on the backend, which includes metadata that tells me how to rehydrate upon retrieval into a business model (and then layer on the notion of “document” on top of that).

I seem to remember not being able to do this in 1.0, where even Rob himself might have been the one to tell me that (or perhaps Ashley). I just don’t recall:

```javascript
...register('SomeService', SomeService)...

```

Perhaps later on, 1.0 was enhanced to allow this. Maybe I missed it in the documentation. I never did revisit the issue. In 1.0, we were taught to stay away from the DI container except in very specific circumstances.

So I did…

**It would be quite useful to be able to rehydrate right from string-based metadata (rather than set up a giant `switch` statement, or write a lot of specific code for each document type).** I could store `‘Itb’` as a meta key, and resolve as `metaKey + ‘Document’`, for example.

---

<div class="post-metadata">

**Author:** ![bigopon](https://yyz1.discourse-cdn.com/flex027/user_avatar/discourse.aurelia.io/bigopon/32/18_2.png) [@bigopon](https://discourse.aurelia.io/u/bigopon)\
**Post date:** [December 24, 2025, 3:26am UTC](https://discourse.aurelia.io/t/au-2-0-downstream-error-after-resolving-a-factory-with-a-string/6557/6 "2025-12-24T03:26:56Z")

</div>

there’s nothing wrong with having a string as a key to resolve some instances. What we have in this thread is the ability to resolve a key to a factory via `factory` resolver. I think v1 allows it, but I’m not able to replicate the scenario you have. I’ve prepared some basic repro here [https://gist.dumber.app/?gist=43495e4c30d304b065c79c5318568388](https://gist.dumber.app/?gist=43495e4c30d304b065c79c5318568388), can you help fork and make it similar to the code you got?

---

<div class="post-metadata">

**Author:** ![estaylorco](https://yyz1.discourse-cdn.com/flex027/user_avatar/discourse.aurelia.io/estaylorco/32/1887_2.png) [@estaylorco](https://discourse.aurelia.io/u/estaylorco)\
**Post date:** [December 24, 2025, 3:40am UTC](https://discourse.aurelia.io/t/au-2-0-downstream-error-after-resolving-a-factory-with-a-string/6557/7 "2025-12-24T03:40:30Z")

</div>

I’m a little confused. Your repro is Au 1.0. I’m migrating to 2.0.

What you’ve shown, though, confirms what I said in my last post that I didn’t even know this was available in Au 1.0. For example, I didn’t know until now (after all these years) that we could use `Factory.of` at the point of global registration. I used it only in constructor-based injection (`@inject(Factory.of(...)`).

_(I wish I had known that we could do this in 1.0. That would’ve allowed me to streamline my code)._

**So, is the conclusion here that 2.0 has no analog for this:**

```javascript
aurelia.container.registerResolver('ItbFactory', Factory.of(MyFactory));

```

Are you able to reproduce the error I’m getting in 2.0 with the approach I gave earlier in this thread?

---

<div class="post-metadata">

**Author:** ![bigopon](https://yyz1.discourse-cdn.com/flex027/user_avatar/discourse.aurelia.io/bigopon/32/18_2.png) [@bigopon](https://discourse.aurelia.io/u/bigopon)\
**Post date:** [December 24, 2025, 3:54am UTC](https://discourse.aurelia.io/t/au-2-0-downstream-error-after-resolving-a-factory-with-a-string/6557/8 "2025-12-24T03:54:20Z")

</div>

in v2, the code you had earlier won’t work, so it’s guaranteed an error. What I was asking for is the code you got with v1 that enables a similar capability in v1. For v2, the API would be like this once it’s supported:

```typescript
container.register(Registration.singleton('ItbFactory', MyFactory))

...

factory = resolve(factory('ItbFactory'))

```

---

<div class="post-metadata">

**Author:** ![estaylorco](https://yyz1.discourse-cdn.com/flex027/user_avatar/discourse.aurelia.io/estaylorco/32/1887_2.png) [@estaylorco](https://discourse.aurelia.io/u/estaylorco)\
**Post date:** [December 24, 2025, 4:18am UTC](https://discourse.aurelia.io/t/au-2-0-downstream-error-after-resolving-a-factory-with-a-string/6557/9 "2025-12-24T04:18:13Z")

</div>

Ah, sorry about that. I misunderstood what you were after.

I would adjust your example to this:

```javascript
container.register(Registration.transient('ItbDocument', ItbDocument))

...

documentFactory = resolve(factory('ItbDocument'))

```

If you recall, at the outset this morning, I confused both of us with naming conventions I hadn’t adjusted 🫢 .

Looking at the last line above, if we could do that, call factory on a string, then my problem would be solved (as it would be for others looking to leverage runtime hydration and composition).

The only problem I see with your 1.0 repro is this:

```javascript
static inject = ['ItbDocument'];

```

This, too, in 1.0, if possible, would be a problem:

```javascript
@inject(Factory.of('ItbDocument'))

```

In the cases above, the string can’t be parameterized. It has to be hard-coded, which is not good.

The 2.0 idiom is definitely superior in this case.

---

<div class="post-metadata">

**Author:** ![estaylorco](https://yyz1.discourse-cdn.com/flex027/user_avatar/discourse.aurelia.io/estaylorco/32/1887_2.png) [@estaylorco](https://discourse.aurelia.io/u/estaylorco)\
**Post date:** [December 24, 2025, 4:23am UTC](https://discourse.aurelia.io/t/au-2-0-downstream-error-after-resolving-a-factory-with-a-string/6557/10 "2025-12-24T04:23:03Z")

</div>

I just noticed a subtlety in your example. You registered a singleton; I’m thinking in terms of a transient…perhaps erroneously.

To my mind, we would do this:

```javascript
container.register(Registration.transient('ItbDocument', ItbDocument))
documentFactory = resolve(factory('ItbDocument'))

```

But, then, if `factory` resolves a new instance each time, I can understand why you showed me this:

```javascript
container.register(Registration.singleton('ItbDocument', ItbDocument))
documentFactory = resolve(factory('ItbDocument'))

```

This would be the difference between property-based resolution and constructor-based resolution (or static injection), if I understand 2.0 correctly.

---

<div class="post-metadata">

**Author:** ![estaylorco](https://yyz1.discourse-cdn.com/flex027/user_avatar/discourse.aurelia.io/estaylorco/32/1887_2.png) [@estaylorco](https://discourse.aurelia.io/u/estaylorco)\
**Post date:** [January 18, 2026, 4:02am UTC](https://discourse.aurelia.io/t/au-2-0-downstream-error-after-resolving-a-factory-with-a-string/6557/11 "2026-01-18T04:02:30Z")

</div>

Thank you @bigopon for implementing string-based resolution of factories!

Once I installed RC, I modified my test harness in this way:

```javascript
@customElement('test-module')
export class TestModule {
  constructor() {
    ...
    this.myWorkModelFactory = resolve(factory('PipelineMyWorkModel'));
  }

  bound() {
    if (!this.myWorkMgr.myWorkCount) {
      const myWork = [];

      for (let _i = 9; _i >= 0; _i--) {
        const myWorkModel = this.myWorkModelFactory(
          {
            name: 'Project with Long Name ' + _i,
            storeNumber: Math.floor(Math.random() * 4000),
            jobsiteProfile: 1,
          },
          undefined,
          { validatePartial: false },
        );

        // const myWorkModel = new PipelineMyWorkModel().init(
        // {
        // name: 'Project with Long Name ' + _i,
        // storeNumber: Math.floor(Math.random() * 4000),
        // jobsiteProfile: 1,
        // },
        // undefined,
        // { validatePartial: false },
        // );

        myWork.push(myWorkModel);
      }

      this.myWorkMgr.addMyWork(myWork);
      this.myWorkMgr.loadFirstMyWork();
    }
  }
}

```

Worked like a charm! I can now abandon the “init” pattern. Also, this will greatly facilitate rehydrating session.

Thanks, again!

---

<div class="post-metadata">

**Author:** ![Lisa](https://avatars.discourse-cdn.com/v4/letter/l/f08c70/32.png) [@Lisa](https://discourse.aurelia.io/u/Lisa)\
**Post date:** [February 5, 2026, 11:26pm UTC](https://discourse.aurelia.io/t/au-2-0-downstream-error-after-resolving-a-factory-with-a-string/6557/12 "2026-02-05T23:26:27Z")

</div>

not compatible with Aurelia 2.0.  
Factory() does not accept a string key; it only takes a constructable (class). The container fails when you actually call the factory because it cannot decide what to instantiate when you supply a string.

This is true:  
this.documentFactory = resolve(factory(ItbDocument));  
this.document = this.documentFactory();

resolve(factory(‘ItbDocument’));  
String keys are not used for factory construction, but rather for container lookup. that the Factory.of() functionality of au1 does not extend to au2.

---

<div class="post-metadata">

**Author:** ![estaylorco](https://yyz1.discourse-cdn.com/flex027/user_avatar/discourse.aurelia.io/estaylorco/32/1887_2.png) [@estaylorco](https://discourse.aurelia.io/u/estaylorco)\
**Post date:** [February 6, 2026, 2:03am UTC](https://discourse.aurelia.io/t/au-2-0-downstream-error-after-resolving-a-factory-with-a-string/6557/13 "2026-02-06T02:03:11Z")

</div>

I’m not sure I understand what you mean.

What, exactly, is not compatible with Aurelia 2.0? With Aurelia 2.0 RC, we can now resolve a factory using string keys.

Or are you saying that `Factory.of()` in Aurelia 1.0 doesn’t accept strings, only a constructible class?

In Aurelia 2.0, there is a decorator-based approach to factories:

```javascript
@inject(factory(MyService))
export class MyClass {}

```

I’m not sure if string-based keys work in Aurelia 2.0 with this approach.

---

<div class="post-metadata">

**Author:** ![elitemike](https://yyz1.discourse-cdn.com/flex027/user_avatar/discourse.aurelia.io/elitemike/32/690_2.png) [@elitemike](https://discourse.aurelia.io/u/elitemike)\
**Post date:** [February 6, 2026, 2:53am UTC](https://discourse.aurelia.io/t/au-2-0-downstream-error-after-resolving-a-factory-with-a-string/6557/14 "2026-02-06T02:53:25Z")

</div>

Feels like a bot answer. I could be wrong. I just had a similar style response on my thread

---

<div class="post-metadata">

**Author:** ![estaylorco](https://yyz1.discourse-cdn.com/flex027/user_avatar/discourse.aurelia.io/estaylorco/32/1887_2.png) [@estaylorco](https://discourse.aurelia.io/u/estaylorco)\
**Post date:** [February 6, 2026, 3:09am UTC](https://discourse.aurelia.io/t/au-2-0-downstream-error-after-resolving-a-factory-with-a-string/6557/15 "2026-02-06T03:09:16Z")

</div>

That would be a shame. I got excited there for a minute when I saw someone was posting for the first time.

---

<div class="post-metadata">

**Author:** ![carol2](https://avatars.discourse-cdn.com/v4/letter/c/3be4f8/32.png) [@carol2](https://discourse.aurelia.io/u/carol2)\
**Post date:** [February 13, 2026, 6:34am UTC](https://discourse.aurelia.io/t/au-2-0-downstream-error-after-resolving-a-factory-with-a-string/6557/16 "2026-02-13T06:34:18Z")

</div>

in **Aurelia 2** , `factory()` doesn’t work with string keys like Au 1 did. it expects a class/constructable, not `'ItbDocument'`.

so this:

```auto
resolve(factory('ItbDocument'))

```

is wrong.

use:

```auto
resolve(factory(ItbDocument))

```

or skip `factory()` and just:

```auto
() => resolve('ItbDocument')

```

`factory()` in Aurelia 2 is class-based. that’s why you’re getting the downstream error.
