---
url: https://masyaka.github.io/injecute/errors.md
description: Every error injecute throws, with how to fix it.
---

# Errors

Every error injecute throws is an `InjecuteError` with a stable `code`, the resolution `path`
(which service needed what), a `docs` link to the page below, and a message with a hint.
Branch on `code`, not on message text.

| Code | Meaning |
| --- | --- |
| [`INJECUTE_NOT_REGISTERED`](./not-registered.md) | No service is registered under this key |
| [`INJECUTE_ALREADY_REGISTERED`](./already-registered.md) | The key is already registered in this container or a parent |
| [`INJECUTE_CIRCULAR_DEPENDENCY`](./circular-dependency.md) | Services depend on each other in a cycle |
| [`INJECUTE_NOTHING_TO_REPLACE`](./nothing-to-replace.md) | A registration replaces a key that nothing is registered under |
| [`INJECUTE_NO_PREVIOUS_DEFINITION`](./no-previous-definition.md) | A service depends on itself but there is nothing to decorate |
| [`INJECUTE_INVALID_FACTORY`](./invalid-factory.md) | The factory is not a function or class |
| [`INJECUTE_INVALID_DEPENDENCY`](./invalid-dependency.md) | A dependency is not a key, optional(key), collect(tag) or a function |
| [`INJECUTE_CLASS_NOT_CONSTRUCTED`](./class-not-constructed.md) | A class was called without new |
| [`INJECUTE_RESOLUTION_FAILED`](./resolution-failed.md) | A factory threw (or its promise rejected) while creating a service |
| [`INJECUTE_NOT_A_FUNCTION`](./not-a-function.md) | call() was used on a service that is not a function |
| [`INJECUTE_NAMESPACE_CONFLICT`](./namespace-conflict.md) | The namespace name is already used by a service |
| [`INJECUTE_NAMESPACE_RESULT`](./namespace-result.md) | A namespace callback returned something other than a new container |
| [`INJECUTE_EXTENSION_RESULT`](./extension-result.md) | An extension returned a container that is not this one or its child |
| [`INJECUTE_SEALED`](./sealed.md) | The container is sealed |
| [`INJECUTE_DISPOSED`](./disposed.md) | The container is disposed |
| [`INJECUTE_DISPOSE_FAILED`](./dispose-failed.md) | Some services failed to dispose |
| [`INJECUTE_WIRING_FAILED`](./wiring-failed.md) | The wiring check found services that are missing or fail |
| [`INJECUTE_INVALID_OPTION`](./invalid-option.md) | An option is not supported here |
| [`INJECUTE_UNKNOWN_EVENT`](./unknown-event.md) | Unknown event name |
| [`INJECUTE_READ_ONLY`](./read-only.md) | The object is read-only |
| [`INJECUTE_INVALID_HOOK`](./invalid-hook.md) | A lifecycle hook is not registered correctly |
| [`INJECUTE_UNDO_FAILED`](./undo-failed.md) | A lifecycle hook could not be undone |
| [`INJECUTE_LIFECYCLE_STOPPED`](./lifecycle-stopped.md) | The lifecycle of this container was stopped |

## Hints in browser bundles

Bundlers that build for browsers leave the hints out of error messages, to keep the bundle small (about
1.5 kB gzipped). Messages keep what happened and the docs link; `error.code` and `error.docs` are the
same everywhere.

| Where it runs | Hints in messages |
| --- | --- |
| Node.js, Deno, Bun, server-side rendering, browsers without a bundler | always |
| Vite and webpack, development (the dev server, `--mode development`) | yes |
| Vite and webpack, production builds | no |
| esbuild, Rolldown | no, unless you add the `development` condition (`conditions: ['development']`) |

To have them in any build, import `injecute/hints` where you want them:

```ts
// in development only, with any bundler
if (import.meta.env.DEV) await import('injecute/hints');

// or in every build (staging, or debugging a production build)
import 'injecute/hints';
```

Without a bundler, and on servers, the import does nothing: those messages have the hints already. An
error thrown before a dynamic `import()` finishes has no hint; a static import doesn't have that gap.
