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

SpringAiSkillAdvisor.Builder.userSkillsDirectory(Resource) calls resource.getFile(), which only works for file-system-backed Spring Resources; when conversion throws IOException the builder rethrows it as IllegalArgumentException. Classpath resources inside a JAR or remote resources cannot be converted to a file path.

Source

Thrown at spring-ai-alibaba-graph-core/src/main/java/com/alibaba/cloud/ai/graph/skills/SpringAiSkillAdvisor.java:320

		/**
		 * 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. Point userSkillsDirectory at an exploded directory on disk instead of a classpath/JAR resource
  2. Unpack skill resources at startup to a temp directory and pass that path
  3. Load skills via ClasspathSkillRegistry, which handles JAR-packaged skills
  4. Ensure the Resource resolves to a real file (resource.getFile() must succeed)

Example fix

// before
advisor.builder().userSkillsDirectory(new ClassPathResource("skills"));
// after
advisor.builder().userSkillsDirectory(new FileSystemResource("/opt/app/skills"));
Defensive patterns

Strategy: fallback

Validate before calling

Resource r = new ClassPathResource("skills");
boolean usable = r.exists();
try { r.getFile(); } catch (IOException e) { usable = false; } // jar resources fail here

Type guard

boolean isFileBacked(Resource r) { try { return r != null && r.exists() && r.getFile().isFile(); } catch (IOException e) { return false; } }

Try / catch

try { builder.userSkillsDirectory(resource); } catch (IllegalArgumentException e) { log.warn("Resource not file-backed, falling back to classpath registry"); }

Prevention

When it happens

Trigger: Passing a Resource that is not backed by a real file (e.g. ClassPathResource pointing into a packaged JAR, ByteArrayResource, UrlResource) to userSkillsDirectory(...).

Common situations: Skills bundled in a Spring Boot fat JAR where classpath resources are jar: URLs, not files; running from Docker image without exploded classes; devtools vs packaged behavior differences.

Understand the failure class

Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.

Related errors


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