{"record":{"id":"952b8d0259bfef99","repo":"alibaba/nacos","slug":"base-directory-cannot-be-blank","errorCode":null,"errorMessage":"Base directory cannot be blank","messagePattern":"Base directory cannot be blank","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"api/src/main/java/com/alibaba/nacos/api/ai/model/skills/SkillUtils.java","lineNumber":300,"sourceCode":"     * @param skill the Skill object to sync\n     * @param baseDir the base directory path where the skill directory will be created\n     * @param strategy the strategy for handling existing directories\n     * @throws IOException if file operations fail\n     * @throws IllegalArgumentException if skill is null or skill name is blank\n     * @throws FileAlreadyExistsException if directory exists and strategy is FAIL\n     */\n    public static void syncToLocal(Skill skill, String baseDir, ExistingDirectoryStrategy strategy)\n        throws IOException {\n        if (skill == null) {\n            throw new IllegalArgumentException(\"Skill cannot be null\");\n        }\n        \n        if (StringUtils.isBlank(skill.getName())) {\n            throw new IllegalArgumentException(\"Skill name cannot be blank\");\n        }\n        \n        if (StringUtils.isBlank(baseDir)) {\n            throw new IllegalArgumentException(\"Base directory cannot be blank\");\n        }\n        \n        if (strategy == null) {\n            strategy = ExistingDirectoryStrategy.OVERWRITE;\n        }\n        \n        // Create skill directory path: {baseDir}/{skillName}\n        Path basePath = Paths.get(baseDir);\n        Path skillDir = basePath.resolve(skill.getName());\n        \n        // Delegate to core implementation\n        syncToLocalCore(skill, skillDir, basePath, strategy);\n    }\n    \n    /**\n     * Sync Skill object to local directory with custom skill directory name.\n     * Creates the skill directory structure, SKILL.md file, and resource files.\n     * Uses OVERWRITE strategy by default.","sourceCodeStart":282,"sourceCodeEnd":318,"githubUrl":"https://github.com/alibaba/nacos/blob/9b989acdf181d00898f2e8839257bb2b2a3cefe3/api/src/main/java/com/alibaba/nacos/api/ai/model/skills/SkillUtils.java#L282-L318","documentation":"Thrown by the three-argument SkillUtils.syncToLocal as an IllegalArgumentException when baseDir is blank (null, empty, or whitespace). The base directory is the root under which the skill directory is created; a blank value cannot be resolved into a valid filesystem path.","triggerScenarios":"Calling syncToLocal(skill, null, strategy) or syncToLocal(skill, \"\", strategy). Common when a configuration property for the skills root directory was not set or resolved to empty.","commonSituations":"The 'nacos.ai.skill.base-dir' (or equivalent) config key was missing from the environment; a system property placeholder (${skill.dir}) was never substituted; the directory was read from an empty environment variable.","solutions":["Set the base directory configuration to an absolute, writable path (e.g. /var/nacos/skills).","Read the config with a required/default fallback so it is never blank.","Validate the resolved baseDir before the sync loop and fail fast with a clear config error."],"exampleFix":"// before\nString baseDir = System.getenv(\"SKILL_DIR\"); // unset -> null\nSkillUtils.syncToLocal(skill, baseDir, OVERWRITE); // throws\n\n// after\nString baseDir = System.getenv(\"SKILL_DIR\");\nif (StringUtils.isBlank(baseDir)) {\n    baseDir = \"/var/nacos/skills\";\n}\nSkillUtils.syncToLocal(skill, baseDir, OVERWRITE); // ok","handlingStrategy":"validation","validationCode":"if (StringUtils.isBlank(baseDir)) {\n    throw new IllegalStateException(\"Skill base directory is not configured (skill.baseDir)\");\n}\nSkillUtils.syncToLocal(skill, baseDir, strategy);","typeGuard":"static boolean isBaseDirConfigured(String baseDir) {\n    return !StringUtils.isBlank(baseDir);\n}","tryCatchPattern":null,"preventionTips":["Add a startup health check that fails if the skills base-dir config is missing.","Provide a documented default so deployments work out-of-the-box.","Resolve config placeholders (${...}) before passing to syncToLocal."],"tags":["java","nacos","ai","skills","validation","config"],"backgroundTag":null,"analyzedSha":"9b989acdf181d00898f2e8839257bb2b2a3cefe3","analyzedAt":"2026-08-14T07:17:31.569Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}