langgenius/dify · error · NotFound
App entity not found
Error message
App entity not found
What it means
HTTP 404 raised in POST /console/explore/installed-apps after a RecommendedApp row was found, but db.session.get(App, app_id) returned None. This indicates a data-integrity break: the recommended_apps row references an App primary key that no longer exists.
Source
Thrown at api/controllers/console/explore/installed_app.py:210
@login_required
@account_initialization_required
@cloud_edition_billing_resource_check("apps")
@console_ns.expect(console_ns.models[InstalledAppCreatePayload.__name__])
@console_ns.response(200, "Success", console_ns.models[SimpleMessageResponse.__name__])
@with_current_tenant_id
@model_validate(InstalledAppCreatePayload)
def post(self, req_data: InstalledAppCreatePayload, current_tenant_id: str):
recommended_app = db.session.scalar(
select(RecommendedApp).where(RecommendedApp.app_id == req_data.app_id).limit(1)
)
if recommended_app is None:
raise NotFound("Recommended app not found")
app = db.session.get(App, req_data.app_id)
if app is None:
raise NotFound("App entity not found")
if not app.is_public:
raise Forbidden("You can't install a non-public app")
installed_app = db.session.scalar(
select(InstalledApp)
.where(and_(InstalledApp.app_id == req_data.app_id, InstalledApp.tenant_id == current_tenant_id))
.limit(1)
)
if installed_app is None:
# todo: position
recommended_app.install_count += 1
new_installed_app = InstalledApp(
app_id=req_data.app_id,
tenant_id=current_tenant_id,
app_owner_tenant_id=app.tenant_id,View on GitHub (pinned to ef8544b173)
Solutions
- Report to an admin to remove the orphaned RecommendedApp row (or re-create the missing App) — this is a server-side data inconsistency, not a client mistake.
- As an admin, run a sweep: SELECT * FROM recommended_apps ra LEFT JOIN apps a ON ra.app_id = a.id WHERE a.id IS NULL; and delete the orphans.
- On the client, fall back to the general Explore listing and skip the broken entry.
- Add a cascade or periodic cleanup job so deleting an App also removes its RecommendedApp row.
Example fix
-- before: orphan recommended_apps row points at deleted app SELECT ra.app_id FROM recommended_apps ra LEFT JOIN apps a ON a.id = ra.app_id WHERE a.id IS NULL; -- after: remove orphans so the listing stays consistent DELETE ra FROM recommended_apps ra LEFT JOIN apps a ON a.id = ra.app_id WHERE a.id IS NULL;
Defensive patterns
Strategy: try-catch
Validate before calling
// Client cannot validate server-side data integrity; preflight only confirms recommend status
async function appExists(appId) {
const r = await fetch(`/console/explore/apps`);
const list = await r.json();
return (list.data || []).some(a => a.app_id === appId);
} Try / catch
try {
await post('/console/explore/installed-apps', { app_id });
} catch (e) {
if (e.status === 404 && /App entity not found/.test(e.message)) {
reportOrphanToAdmin(app_id); // data integrity issue, server-side fix required
} else throw e;
} Prevention
- Treat 'App entity not found' as a server data-integrity defect; escalate to an admin.
- Admins should cascade App deletion to recommended_apps to prevent orphans.
- Periodic integrity sweep: LEFT JOIN apps on recommended_apps.app_id for NULLs.
When it happens
Trigger: POST /console/explore/installed-apps with an app_id that exists in recommended_apps but whose corresponding row in the apps table has been deleted (hard delete) or never committed. The RecommendedApp foreign-key reference is dangling.
Common situations: An admin deleted the App record while the RecommendedApp entry was left in place; a partial/rolled-back migration; manual DB surgery that removed apps without cleaning recommended_apps; multi-tenant workspace teardown that missed the explore table.
Related errors
- Recommended app not found
- You can't install a non-public app
- Installed app not found
- You can't uninstall an app owned by the current tenant
- app_unavailable
AI-assisted analysis of langgenius/dify@ef8544b173 (2026-08-12).
Data as JSON: /api/errors/baeeb9cca455eb36.
Report an issue: GitHub.