alibaba/spring-ai-alibaba · error · IllegalArgumentException

Cannot convert resource to file system path:

Error message

Cannot convert resource to file system path: 

What it means

SkillPromptAugmentAdvisor.Builder.userSkillsDirectory accepts a Spring Resource; to use it as a skills directory it must resolve to a real file-system path via resource.getFile(). When the resource cannot be converted (e.g. classpath or URL resource without a backing file), the IOException is rethrown as IllegalArgumentException.

Source

Thrown at spring-ai-alibaba-graph-core/src/main/java/com/alibaba/cloud/ai/graph/advisors/SkillPromptAugmentAdvisor.java:283

		/**
		 * Set the user skills directory from a Spring Resource.
		 * <p><b>Optional</b>: Defaults to <code>~/saa/skills</code> if not specified.
		 * <p>The Resource will be converted to a file system path. If the resource cannot be
		 * resolved to a file (e.g., it's inside a JAR), an IllegalArgumentException will be thrown.
		 *
		 * @param resource the Resource pointing to the user-level skills directory
		 * @return this builder
		 * @throws IllegalArgumentException if the resource cannot be converted to a file system path
		 */
		public Builder userSkillsDirectory(Resource resource) {
			try {
				if (resource != null && resource.exists()) {
					File file = resource.getFile();
					this.userSkillsDirectory = file.getAbsolutePath();
				}
			}
			catch (IOException e) {
				throw new IllegalArgumentException("Cannot convert resource to file system path: " + resource, e);
			}
			return this;
		}

		/**
		 * Set the project skills directory.
		 * <p><b>Optional</b>: Defaults to <code>classpath:skills</code> or <code>./skills</code> if not specified.
		 *
		 * @param projectSkillsDirectory the project skills directory path
		 * @return this builder
		 */
		public Builder projectSkillsDirectory(String projectSkillsDirectory) {
			this.projectSkillsDirectory = projectSkillsDirectory;
			return this;
		}

		/**
		 * Set the project skills directory from a Spring Resource.

View on GitHub (pinned to f82da0b50f)

Solutions

  1. Use a FileSystemResource or a plain String directory path pointing to an exploded on-disk directory
  2. Unpack classpath skills to a temp directory at startup (e.g. FileSystemResource of Path) before passing it
  3. Check resource.getURI() scheme: only 'file:' resources support getFile()
  4. Ensure the directory exists and the application has read access before building the advisor

Example fix

// before
builder.userSkillsDirectory(new ClassPathResource("skills"));
// after
Path dir = Path.of(System.getProperty("user.home"), ".myapp", "skills");
Files.createDirectories(dir);
builder.userSkillsDirectory(new FileSystemResource(dir.toFile()));
Defensive patterns

Strategy: validation

Validate before calling

Resource r = ...;
if (!"file".equals(r.getURI().getScheme()) || !r.exists())
    throw new IllegalArgumentException("userSkillsDirectory must be an existing file-system directory");

Type guard

static boolean isFileSystemResource(Resource r) {
    try { return r.exists() && "file".equals(r.getURI().getScheme()); }
    catch (IOException e) { return false; }
}

Try / catch

try { builder.userSkillsDirectory(res); } catch (IllegalArgumentException e) { log.error("resolve skills dir to a real path", e); }

Prevention

When it happens

Trigger: Calling .userSkillsDirectory(new ClassPathResource("skills")) or any Resource backed by a jar/URL rather than the file system, so Resource.getFile() throws FileNotFoundException (an IOException).

Common situations: App packaged as a fat jar where classpath resources live inside the archive; using ResourceLoader-provided resources like classpath: or https: URLs; pointing the builder at a non-existent resource that still passes through the catch on getFile().

Understand the failure class

Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.

Related errors


AI-assisted analysis of alibaba/spring-ai-alibaba@f82da0b50f (2026-09-09). Data as JSON: /api/errors/3483c54539e750e7. Report an issue: GitHub.