{"record":{"id":"bb69eb8edd4274f6","repo":"alibaba/spring-ai-alibaba","slug":"watchservice","errorCode":null,"errorMessage":"启动 WatchService 失败，将不进行热更新: {}","messagePattern":"启动 WatchService 失败，将不进行热更新: (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"spring-ai-alibaba-admin/spring-ai-alibaba-admin-server-start/src/main/java/com/alibaba/cloud/ai/studio/admin/repository/impl/FileModelConfigRepository.java","lineNumber":197,"sourceCode":"                        for (WatchEvent<?> event : key.pollEvents()) {\n                            Path changed = (Path) event.context();\n                            if (changed != null && configPath.getFileName().equals(changed.getFileName())) {\n                                try {\n                                    Map<Long, ModelConfigDO> data = loadFromFile(configPath);\n                                    snapshot.set(Collections.unmodifiableMap(data));\n                                    log.info(\"模型配置热更新成功，数量: {}\", data.size());\n                                } catch (Exception e) {\n                                    log.error(\"模型配置热更新失败，沿用旧配置: {}\", e.getMessage(), e);\n                                }\n                            }\n                        }\n                    } finally {\n                        key.reset();\n                    }\n                }\n            });\n        } catch (Exception e) {\n            log.warn(\"启动 WatchService 失败，将不进行热更新: {}\", e.getMessage());\n        }\n    }\n    \n    @Override\n    public ModelConfigDO findById(Long id) {\n        return snapshot.get().get(id);\n    }\n    \n    @Override\n    public boolean existsById(Long id) {\n        return snapshot.get().containsKey(id);\n    }\n    \n    @Override\n    public List<ModelConfigDO> list(String name, String provider, Integer status, int offset, int limit) {\n        List<ModelConfigDO> all = new ArrayList<>(snapshot.get().values());\n        return all.stream().filter(m -> name == null || m.getName().contains(name))\n                .filter(m -> provider == null || provider.isBlank() || provider.equalsIgnoreCase(m.getProvider()))","sourceCodeStart":179,"sourceCodeEnd":215,"githubUrl":"https://github.com/alibaba/spring-ai-alibaba/blob/f82da0b50f35744c13968191be2b1cd2452ef550/spring-ai-alibaba-admin/spring-ai-alibaba-admin-server-start/src/main/java/com/alibaba/cloud/ai/studio/admin/repository/impl/FileModelConfigRepository.java#L179-L215","documentation":"FileModelConfigRepository watches the model-config file directory with a JDK WatchService to hot-reload config changes. If the WatchService cannot be started (directory doesn't exist, no filesystem watch support, insufficient permissions), this warning is logged and hot reloading is disabled; the repo falls back to the snapshot loaded at startup.","triggerScenarios":"afterPropertiesSet -> startWatchService throws when calling FileSystems.getDefault().newWatchService(), path.register(...), or dir.exists()/mkdirs fails: config directory missing or unreadable, filesystem without inotify support (some network mounts, containers with limits), or too many open files / watch limits exceeded.","commonSituations":"Running the admin server in a container with a low inotify watch limit; config dir on NFS/CIFS mounts; read-only filesystem; running as a user without permission to the model-config directory.","solutions":["Verify the model-config directory exists and is readable/writable by the process user; create it if missing","Check filesystem watch support and raise inotify limits (e.g. fs.inotify.max_user_watches) or move config to a local disk","Check ulimit -n / fd limits if 'too many open files' appears in the exception message","Restart the application to reload config manually if hot update is not critical"],"exampleFix":"// before\nlog.warn(\"启动 WatchService 失败，将不进行热更新: {}\", e.getMessage());\n// after\nlog.warn(\"启动 WatchService 失败，将不进行热更新: {}\", e.getMessage(), e); // log full stack to diagnose dir/permission issue","handlingStrategy":"fallback","validationCode":"java.nio.file.Path dir = Paths.get(configDir);\nif (!java.nio.file.Files.isDirectory(dir) || !java.nio.file.Files.isReadable(dir)) {\n    throw new IllegalStateException(\"config dir missing/unreadable: \" + dir);\n}","typeGuard":null,"tryCatchPattern":"try { repo.afterPropertiesSet(); } catch (Exception e) { log.warn(\"hot reload disabled: {}\", e.getMessage(), e); /* schedule periodic full reload instead */ }","preventionTips":["Ensure the config directory exists and is writable before startup","Raise inotify watch limits in containers (fs.inotify.max_user_watches)","Avoid placing watched dirs on NFS/network mounts"],"tags":["filesystem","watchservice","hot-reload","config"],"backgroundTag":"file-watch-failed","analyzedSha":"f82da0b50f35744c13968191be2b1cd2452ef550","analyzedAt":"2026-09-09T15:32:42.421Z","contentChangedAt":"2026-09-09T15:32:42.421Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}