---
title: "DF0037: Duplicate Service Provider"
description: "A service is already provided under \"{id}\"."
canonical_url: "https://devfra.me/errors/df0037"
---
# DF0037: Duplicate Service Provider

> A service is already provided under "\{id}".

## Message

> A service is already provided under "`{id}`".

## Cause

`ctx.services` holds exactly one provider per service id. A second `provide()` under the same id throws instead of silently replacing a service another devframe may already hold a reference to.

## Example

```ts
// ✗ Bad: provided twice
ctx.services.provide('my-plugin:sources', hostA)
ctx.services.provide('my-plugin:sources', hostB)

// ✓ Good: revoke the previous provider first
const revoke = ctx.services.provide('my-plugin:sources', hostA)
revoke()
ctx.services.provide('my-plugin:sources', hostB)
```

## Fix

- Revoke the existing provider first; `provide()` returns a revoke function.
- If the collision is between two unrelated devframes, namespace the id with your devframe id (`<plugin-id>:<service>`), the same rule RPC function names follow.
- Guard idempotent setup paths with `ctx.services.has(id)`.

## Source

- [`packages/devframe/src/node/host-services.ts`](https://github.com/devframes/devframe/blob/main/packages/devframe/src/node/host-services.ts): `provide()` throws this when the id is already taken.


## Sitemap

See the full [sitemap](https://devfra.me/sitemap.md) for all pages.
