HeyPuter/puter · warning · HttpError
app_index_url_already_in_use
app_index_url_already_in_use
Error message
App index_url already in use
What it means
Thrown by `#ensureIndexUrlNotAlreadyInUse` when an app row already references the given `index_url` (or its candidate variants) and isn't excluded by `excludeAppId`. Returns HTTP 400 with legacyCode `app_index_url_already_in_use`, carrying `fields.index_url` and `fields.app_uid` of the conflicting app.
Source
Thrown at src/backend/drivers/apps/AppDriver.js:1180
}
}
if (candidates.size === 0) return null;
const candidateList = [...candidates];
if (hasIndexUrlUniquenessExemption(candidateList)) return null;
return this.appStore.findByIndexUrlCandidates(candidateList, {
excludeAppId,
});
}
async #ensureIndexUrlNotAlreadyInUse({ indexUrl, excludeAppId } = {}) {
const conflictRow = await this.#findIndexUrlConflictRow({
indexUrl,
excludeAppId,
});
if (conflictRow) {
throw new HttpError(400, 'App index_url already in use', {
legacyCode: 'app_index_url_already_in_use',
fields: {
index_url: indexUrl,
app_uid: conflictRow.uid,
},
});
}
}
async #ensurePuterSiteSubdomainIsOwned(indexUrl, user) {
if (!user) return;
const subdomain = this.#extractPuterHostedSubdomain(indexUrl);
if (!subdomain) return;
let row = await this.stores.subdomain.getBySubdomain(subdomain);
if (!row) {
// Deploys create the subdomain and immediately point the app
// at it, so a replica or peer-cache miss here would wronglyView on GitHub (pinned to 908ec23eda)
Solutions
- Point the app at a unique origin/index_url.
- Update or delete the existing app that holds the conflicting index_url first.
- If reassigning within the same app, the update path passes `excludeAppId` so self-conflicts are allowed.
Example fix
// before
driver.create({ object: { name:'a', index_url:'https://x.com/i.html' } });
// another create with same index_url -> 400
// after
await driver.update({ uid: existingApp, object: { index_url:'https://x.com/i.html' } });
// or delete the holder first Defensive patterns
Strategy: validation
Validate before calling
// Resolve candidates like the driver does and check before create
const conflicts = await appStore.findByIndexUrlCandidates([indexUrl], {});
if (conflicts.length) throw new Error('index_url already in use');
await driver.create({ object: { index_url } }); Try / catch
try {
await driver.create({ object });
} catch (e) {
if (e.code === 'app_index_url_already_in_use') { object.index_url = uniqueOrigin(); await driver.create({object}); return; }
throw e;
} Prevention
- Give each app a unique index_url origin.
- Reuse/update existing apps rather than re-creating against the same origin.
- Remember scheme/port variants of an origin also collide.
When it happens
Trigger: Creating/updating an app with an `index_url` that another app already uses, during the non-merge path (`update` with an `excludeAppId` for the current app). `#findIndexUrlConflictRow` resolves origin variants, so scheme/port variants of the same origin also collide.
Common situations: Two apps pointed at the same deployed origin; redeploying to an index_url an abandoned app still holds; CDN/origin reuse across app entries.
Related errors
AI-assisted analysis of HeyPuter/puter@908ec23eda (2026-08-12).
Data as JSON: /api/errors/f2294cdd788b0386.
Report an issue: GitHub.