cakephp/cakephp · error · CakeException

You cannot configure

Error message

You cannot configure `%s`, it already exists in the registry.

What it means

`AbstractLocator::get()` throws a `CakeException` when an instance for the alias already exists in the registry but the caller supplied different configuration options than those it was created with. The registry keeps one instance per alias with fixed options; re-getting it with conflicting options would silently produce inconsistent behavior, so it is rejected.

Solutions

  1. Make the option sets identical across all `get()` calls for that alias, or omit options on subsequent calls
  2. Drop the existing instance first (`$locator->remove('Alias')`) then re-get with the new options
  3. Unify the configuration in one place (e.g. Table's `initialize`/config provider) instead of passing divergent options at call sites

Example fix

// before
$users = $locator->get('Users');
$users2 = $locator->get('Users', ['className' => 'App\Model\Table\CustomUsersTable']); // throws

// after
$users = $locator->get('Users', ['className' => 'App\Model\Table\CustomUsersTable']);
// or: $locator->remove('Users'); $users = $locator->get('Users', ['className' => ...]);
Defensive patterns

Strategy: validation

Validate before calling

$options = $options ?? [];
if ($locator->exists($alias) && $options !== [] && !empty($locator->getConfig($alias))
    && $locator->getConfig($alias) !== $options) {
    $locator->remove($alias);
}

Try / catch

try {
    $instance = $locator->get($alias, $options);
} catch (\Cake\Core\Exception\CakeException $e) {
    if (str_contains($e->getMessage(), 'it already exists in the registry')) {
        $locator->remove($alias);
        $instance = $locator->get($alias, $options);
    } else { throw $e; }
}

Prevention

When it happens

Trigger: Calling `$locator->get('Alias', [...])` when 'Alias' was already instantiated with different options (e.g. different `className`, entity/class options) and `$storeOptions` is non-empty and differs from stored `$this->options[$alias]`.

Common situations: Calling a table twice with different options in one request (e.g. first `$this->fetchTable('Users')`, then with a different className); plugin and app code configuring the same alias differently; tests reusing a locator across configs.

Understand the failure class

Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.

Related errors


AI-assisted analysis of cakephp/cakephp@1128eba9b0 (2026-09-12). Data as JSON: /api/errors/eae358c8df96eda3. Report an issue: GitHub.

Appendix: source

Thrown at src/Datasource/Locator/AbstractLocator.php:60

    protected array $options = [];

    /**
     * {@inheritDoc}
     *
     * @param string $alias The alias name you want to get.
     * @param array<string, mixed> $options The options you want to build the table with.
     * @return TRepo
     * @throws \Cake\Core\Exception\CakeException When trying to get alias for which instance
     *   has already been created with different options.
     */
    public function get(string $alias, array $options = []): RepositoryInterface
    {
        $storeOptions = $options;
        unset($storeOptions['allowFallbackClass']);

        if (isset($this->instances[$alias])) {
            if ($storeOptions && isset($this->options[$alias]) && $this->options[$alias] !== $storeOptions) {
                throw new CakeException(sprintf(
                    'You cannot configure `%s`, it already exists in the registry.',
                    $alias,
                ));
            }

            return $this->instances[$alias];
        }

        $this->options[$alias] = $storeOptions;

        return $this->instances[$alias] = $this->createInstance($alias, $options);
    }

    /**
     * Create an instance of a given classname.
     *
     * @param string $alias Repository alias.
     * @param array<string, mixed> $options The options you want to build the instance with.

View on GitHub (pinned to 1128eba9b0)