{"record":{"id":"a5dc94dc9d175945","repo":"langgenius/dify","slug":"app-not-found-a5dc94","errorCode":null,"errorMessage":"App not found","messagePattern":"App not found","errorType":"http","errorClass":"NotFound","httpStatus":404,"severity":"error","filePath":"api/controllers/console/app/app.py","lineNumber":1017,"sourceCode":"            session.commit()\n\n            # Inherit web app permission from original app\n            if result.app_id and FeatureService.get_system_features().webapp_auth.enabled:\n                try:\n                    # Get the original app's access mode\n                    original_settings = EnterpriseService.WebAppAuth.get_app_access_mode_by_id(app_model.id)\n                    access_mode = original_settings.access_mode\n                except Exception:\n                    # If original app has no settings (old app), default to public to match fallback behavior\n                    access_mode = \"public\"\n\n                # Apply the same access mode to the copied app\n                EnterpriseService.WebAppAuth.update_app_access_mode(result.app_id, access_mode)\n\n            stmt = select(App).where(App.id == result.app_id)\n            app = session.scalar(stmt)\n            if not app:\n                raise NotFound(\"App not found\")\n\n            permission_keys_map = enterprise_rbac_service.RBACService.AppPermissions.batch_get(\n                str(current_tenant_id),\n                current_user.id,\n                [str(app.id)],\n                session=session,\n            )\n            response_model = AppDetailWithSite.model_validate(\n                app,\n                from_attributes=True,\n                context={\"session\": session},\n            ).model_copy(update={\"permission_keys\": permission_keys_map.get(str(app.id), [])})\n            return response_model.model_dump(mode=\"json\"), 201\n\n\n@console_ns.route(\"/apps/<uuid:app_id>/export\")\nclass AppExportApi(Resource):\n    @console_ns.doc(\"export_app\")","sourceCodeStart":999,"sourceCodeEnd":1035,"githubUrl":"https://github.com/langgenius/dify/blob/ef8544b173fd6cd7a8e71df2cab576e52bebbfbc/api/controllers/console/app/app.py#L999-L1035","documentation":"Raised in the app-copy flow after AppService.copy_app returns a result.app_id, when the subsequent SELECT of App by that id yields None. Indicates the freshly copied app row is missing — typically a transaction rollback or concurrent deletion between insert and read. Surfaces as NotFound (404).","triggerScenarios":"POST /console/apps/{app_id}/copy succeeds in copy_app but the follow-up lookup of the new app returns nothing: transaction rolled back, the copy was deleted by another request, or an enterprise webapp_auth side effect raised silently before the read.","commonSituations":"Concurrent deletion of the copied app; database replica lag if reads go to a replica; enterprise webapp_auth update_app_access_mode raises and the surrounding transaction is rolled back; out-of-storage during insert.","solutions":["Retry the copy request once — transient race or rollback often clears.","Check DB logs for transaction rollbacks around the copy time.","Confirm EnterpriseService.WebAppAuth.update_app_access_mode is healthy when webapp_auth is enabled.","Verify primary/replica consistency if reads are routed to a replica."],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"try { return await axios.post(`/apps/${id}/copy`, payload); }\ncatch (e) { if (/App not found/.test(e.message)) { /* retry once; if still failing, escalate */ } }","preventionTips":["Treat a 404 immediately after copy as transient and retry once.","Verify primary/replica consistency if reads use a replica.","Ensure EnterpriseService.WebAppAuth updates do not roll back the copy transaction."],"tags":["apps","copy","transaction","console-api","race-condition"],"backgroundTag":null,"analyzedSha":"ef8544b173fd6cd7a8e71df2cab576e52bebbfbc","analyzedAt":"2026-08-12T05:15:17.394Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}