{"record":{"id":"522c1cb1d361ae4b","repo":"apolloconfig/apollo","slug":"appid-not-unique","errorCode":null,"errorMessage":"appId not unique","messagePattern":"appId not unique","errorType":"exception","errorClass":"ServiceException","httpStatus":500,"severity":"critical","filePath":"apollo-biz/src/main/java/com/ctrip/framework/apollo/biz/service/AppService.java","lineNumber":81,"sourceCode":"\n  public List<App> findAll(Pageable pageable) {\n    Page<App> page = appRepository.findAll(pageable);\n    return page.getContent();\n  }\n\n  public List<App> findByName(String name) {\n    return appRepository.findByName(name);\n  }\n\n  public App findOne(String appId) {\n    return appRepository.findByAppId(appId);\n  }\n\n  @Transactional\n  @ApolloAuditLog(type = OpType.CREATE, name = \"App.create\")\n  public App save(App entity) {\n    if (!isAppIdUnique(entity.getAppId())) {\n      throw new ServiceException(\"appId not unique\");\n    }\n    entity.setId(0);// protection\n    App app = appRepository.save(entity);\n\n    auditService.audit(App.class.getSimpleName(), app.getId(), Audit.OP.INSERT,\n        app.getDataChangeCreatedBy());\n\n    return app;\n  }\n\n  @Transactional\n  @ApolloAuditLog(type = OpType.UPDATE, name = \"App.update\")\n  public void update(App app) {\n    String appId = app.getAppId();\n\n    App managedApp = appRepository.findByAppId(appId);\n    if (managedApp == null) {\n      throw BadRequestException.appNotExists(appId);","sourceCodeStart":63,"sourceCodeEnd":99,"githubUrl":"https://github.com/apolloconfig/apollo/blob/d95fc18d112589efc09ddcbe1507047584d55251/apollo-biz/src/main/java/com/ctrip/framework/apollo/biz/service/AppService.java#L63-L99","documentation":"A ServiceException (HTTP 500) thrown from AppService.save() when an app with the given appId already exists. The uniqueness check isAppIdUnique() queries appRepository.findByAppId(appId) and a non-null result means the appId is taken. Since appId is the primary business key across all of Apollo, a collision is a significant data-integrity event.","triggerScenarios":"POST /apps (AppService.save) with an appId that already exists in the App table. The error fires before any insert is attempted.","commonSituations":"Retried app-creation request after a client timeout (the first request succeeded); two environments or operators creating the same appId; a migration or seed script re-run; appId collision due to a naming convention conflict.","solutions":["Check isAppIdUnique(appId) before calling save().","If the app already exists, retrieve and use it instead of creating a new one.","Ensure app-creation requests are not retried on timeout without first checking existence.","Use a deterministic, unique appId generation strategy to avoid collisions."],"exampleFix":"// before: unconditional creation\nappService.save(app);\n\n// after: idempotent creation\nif (appService.isAppIdUnique(app.getAppId())) {\n    appService.save(app);\n} else {\n    app = appService.findOne(app.getAppId());\n}","handlingStrategy":"validation","validationCode":"// Check appId uniqueness before saving\nif (appService.isAppIdUnique(app.getAppId())) {\n    return appService.save(app);\n} else {\n    // app already exists — return existing instead of creating\n    return appService.findOne(app.getAppId());\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always call isAppIdUnique() before AppService.save() to avoid the ServiceException.","Do not retry app-creation on client timeout without first checking existence.","Use a deterministic appId to avoid accidental collisions."],"tags":["app","duplicate","data-integrity","service-exception","apollo-biz"],"backgroundTag":null,"analyzedSha":"d95fc18d112589efc09ddcbe1507047584d55251","analyzedAt":"2026-08-14T04:00:05.477Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}