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

  1. Choose a unique name; prefix with your username or a slug to avoid collisions.
  2. Before renaming, check availability via the app lookup/name-resolution endpoint (`appStore.getByName`).
  3. If you own the colliding app, delete or rename the other app first.
  4. 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

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.