HeyPuter/puter · warning · HttpError
conflict
conflict
Error message
An app with this name already exists
What it means
Thrown during an app update when the requested new name is already taken by another app. The driver only runs this check when `name` is both provided and actually different from the current app name, querying `appStore.existsByName`. It returns HTTP 409 with legacyCode `conflict`.
Source
Thrown at src/backend/drivers/apps/AppDriver.js:475
object,
options: undefined,
user: actor.user,
sourceAppUid: app.uid,
excludeAppId: app.id,
});
if (joinedApp) {
return joinedApp;
}
await this.#ensureIndexUrlNotAlreadyInUse({
indexUrl: fields.index_url,
excludeAppId: app.id,
});
}
// Name conflict check (only if name is changing)
if (fields.name && fields.name !== app.name) {
if (await this.appStore.existsByName(fields.name)) {
throw new HttpError(
409,
'An app with this name already exists',
{ legacyCode: 'conflict' },
);
}
}
const filetypes = fields.filetype_associations;
delete fields.filetype_associations;
const updated = await this.appStore.update(app.id, fields);
if (filetypes !== undefined) {
await this.appStore.setFiletypeAssociations(app.id, filetypes);
}
this.#emitAppChanged({ app: updated, old_app: app, action: 'updated' });
if (fields.name && fields.name !== app.name) {
this.#emitAppRename({View on GitHub (pinned to 908ec23eda)
Solutions
- Choose a unique name; prefix with your username or a slug to avoid collisions.
- Before renaming, check availability via the app lookup/name-resolution endpoint (`appStore.getByName`).
- If you own the colliding app, delete or rename the other app first.
- Handle the 409 gracefully and prompt the end user for a different name.
Example fix
// before
driver.update({ uid, object: { name: 'myapp' } }); // may 409
// after
const existing = await appStore.getByName('myapp');
if (existing && existing.uid !== uid) {
throw new Error('Name taken, pick another');
}
await driver.update({ uid, object: { name: 'myapp' } }); Defensive patterns
Strategy: validation
Validate before calling
// Check name availability before the update
const taken = await appStore.getByName(newName);
if (taken && taken.uid !== appUid) {
throw new Error(`App name '${newName}' is taken`);
}
await driver.update({ uid: appUid, object: { name: newName } }); Type guard
/** @returns {boolean} name looks unique (caller must confirm against store) */
function isValidAppName(name) {
return typeof name === 'string' && name.trim().length > 0 && name.trim().length <= 64;
} Try / catch
try {
await driver.update({ uid, object: { name } });
} catch (e) {
if (e.code === 'conflict') { /* prompt user for a new name */ return; }
throw e;
} Prevention
- Namespace app names with a user/org prefix to avoid collisions.
- Pre-check name availability before surfacing a rename to the user.
- Clean up test fixtures between runs so stale names don't collide.
When it happens
Trigger: Calling the app update/upsert driver method with `object.name` set to a value already owned by another app (different uid). Example: `driver.update({ uid, object: { name: 'taken-name' } })` where `taken-name` exists. Triggers only when `fields.name && fields.name !== app.name` resolves true.
Common situations: Renaming an app in the Dev Center to a name another user or another of your own apps already holds; importing/deploying an app whose name collides with a built-in or pre-existing app; CI test fixtures that reuse a hardcoded app name without teardown.
Related errors
AI-assisted analysis of HeyPuter/puter@908ec23eda (2026-08-12).
Data as JSON: /api/errors/54d2f30e185530d0.
Report an issue: GitHub.