alibaba/spring-ai-alibaba · error · IllegalArgumentException

skill_name and skill_path must refer to the same skill

Error message

skill_name and skill_path must refer to the same skill

What it means

When both skill_name and skill_path are provided, the tool resolves both via the registry and verifies they denote the same skill (compared by name). If the name and path point to different skills it throws this IllegalArgumentException to prevent reading an ambiguous/unintended skill.

Solutions

  1. Pass only one of skill_name or skill_path, not both, unless you are sure they match.
  2. Rebuild/refresh the SkillRegistry so path mappings reflect current skill names.
  3. Verify the registered name equals the skill at the given path before sending both fields.

Example fix

// before
String content = tool.apply("{\"skill_name\": \"summarizer\", \"skill_path\": \"/skills/translator\"}");
// after
String content = tool.apply("{\"skill_name\": \"summarizer\"}");
Defensive patterns

Strategy: validation

Validate before calling

if (req.skillName != null && req.skillPath != null) {
    var byName = registry.get(req.skillName);
    var byPath = registry.getByPath(req.skillPath);
    if (byName.isPresent() && byPath.isPresent() && !byName.get().getName().equals(byPath.get().getName())) {
        throw new IllegalArgumentException("skill_name/skill_path mismatch");
    }
}

Type guard

boolean consistent(SkillRegistry reg, String name, String path) {
    return name == null || path == null ||
        reg.get(name).equals(reg.getByPath(path));
}

Try / catch

try { return tool.apply(input); } catch (IllegalArgumentException e) { return "Ambiguous skill reference: " + e.getMessage(); }

Prevention

When it happens

Trigger: Invoking the read_skill tool with skill_name="a" and skill_path pointing to skill "b"'s directory; stale registry state where the path mapping changed after the model cached a pair of arguments.

Common situations: LLM combining a remembered skill name with a guessed path; skills renamed or moved on disk so path and name diverge; copy-paste mistakes in hand-built tool calls.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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

Appendix: source

Thrown at spring-ai-alibaba-agent-framework/src/main/java/com/alibaba/cloud/ai/graph/agent/hook/skills/ReadSkillTool.java:111

			logger.error("Unexpected error reading skill: {}", e.getMessage(), e);
			return "Error: " + e.getMessage();
		}
	}

	private String readSkillContent(ReadSkillRequest request) throws IOException {
		String skillName = normalize(request != null ? request.skillName : null);
		String skillPath = normalize(request != null ? request.skillPath : null);
		if (skillName == null && skillPath == null) {
			throw new IllegalArgumentException("Either skill_name or skill_path is required");
		}

		if (skillName != null && skillPath != null) {
			SkillMetadata skillByName = skillRegistry.get(skillName)
					.orElseThrow(() -> new IllegalStateException("Skill not found: " + skillName));
			SkillMetadata skillByPath = skillRegistry.getByPath(skillPath)
					.orElseThrow(() -> new IllegalStateException("Skill not found: " + skillPath));
			if (!skillByName.getName().equals(skillByPath.getName())) {
				throw new IllegalArgumentException("skill_name and skill_path must refer to the same skill");
			}
			return skillRegistry.readSkillContent(skillByName.getName());
		}

		if (skillName != null) {
			return skillRegistry.readSkillContent(skillName);
		}
		return skillRegistry.readSkillContentByPath(skillPath);
	}

	private static String normalize(String value) {
		return StringUtils.hasText(value) ? value.trim() : null;
	}

	/**
	 * Request structure for reading a skill.
	 */
	public static class ReadSkillRequest {

View on GitHub (pinned to f82da0b50f)