alibaba/nacos · error · IllegalStateException
HTTP + response.getStatusCode() + when fetching + respons
Error message
HTTP + response.getStatusCode() + when fetching + response.getUrl()
What it means
Thrown inside SkillsShImportService.search() when the skills.sh search HTTP call returns a non-success status. Because the method wraps non-NacosException errors via dataAccess(), the caller actually receives a NacosException whose message is 'Search skills.sh source failed: HTTP {code} when fetching {url}'. The original IllegalStateException carries the code and URL.
Source
Thrown at plugin-default-impl/nacos-default-ai-importer-plugin/src/main/java/com/alibaba/nacos/plugin/ai/importer/defaultimpl/skill/SkillsShImportService.java:128
SkillsShImportService(String endpoint, int maxItemCount, long maxArtifactSize,
DefaultImportHttpClient httpClient) {
this.endpoint = endpoint;
this.maxItemCount = maxItemCount > 0 ? maxItemCount : DEFAULT_MAX_FILE_COUNT;
this.maxArtifactSize = maxArtifactSize;
this.httpClient = httpClient;
}
@Override
public AiResourceImportCandidatePage search(AiResourceImportContext context)
throws NacosException {
try {
String apiRoot = resolveApiRoot();
int resultLimit = resolveLimit(context.getLimit());
ImportHttpResponse response = fetchUrl(searchUrl(apiRoot,
resolveQuery(context.getQuery()), resolveSearchFetchLimit(resultLimit)));
if (!response.isSuccess()) {
throw new IllegalStateException(
"HTTP " + response.getStatusCode() + " when fetching " + response.getUrl());
}
SkillsShSearchResponse searchResponse =
JacksonUtils.toObj(response.getBody(), SkillsShSearchResponse.class);
AiResourceImportCandidatePage result = new AiResourceImportCandidatePage();
result.setItems(toCandidates(apiRoot, searchResponse, resultLimit));
result.setHasMore(false);
result.setNextCursor(null);
return result;
} catch (NacosException e) {
throw e;
} catch (Exception e) {
throw dataAccess("Search skills.sh source failed: " + e.getMessage(), e);
}
}
@Override
public AiResourceImportArtifact fetch(AiResourceImportContext context,View on GitHub (pinned to 9b989acdf1)
Solutions
- Verify the skills.sh API root endpoint configured for the importer.
- Check skills.sh service availability and retry transient 5xx/429 responses.
- Sanitize/encode the search query to avoid 400-level rejections.
Example fix
// before
AiResourceImportContext ctx = ...;
ctx.setQuery("a b c&d"); // unencoded, may cause 400
importer.search(ctx);
// after
ctx.setQuery(URLEncoder.encode("a b c&d", StandardCharsets.UTF_8));
importer.search(ctx); Defensive patterns
Strategy: try-catch
Validate before calling
// Validate the skills.sh API root and encode the query before searching.
URI root = URI.create(resolveApiRoot());
if (!root.isAbsolute()) throw new IllegalArgumentException("skills.sh apiRoot must be absolute");
String q = URLEncoder.encode(context.getQuery(), StandardCharsets.UTF_8); Try / catch
try {
return importer.search(context);
} catch (NacosException e) {
if (e.getMessage().contains("skills.sh source failed")) {
// surface a user-friendly 'source unavailable, retry later' message
}
throw e;
} Prevention
- URL-encode the search query to avoid 400s.
- Verify the configured skills.sh API root is correct and reachable.
- Retry transient 5xx/429; cache successful search results briefly.
When it happens
Trigger: search() calls fetchUrl(searchUrl(...)); response.isSuccess() is false; the IllegalStateException is thrown, then caught by catch(Exception e) and rethrown as dataAccess('Search skills.sh source failed: ...').
Common situations: The skills.sh API root is misconfigured or unreachable; the service is rate-limiting (429) or down (5xx); an invalid query string triggers a 400; egress firewall blocks skills.sh.
Related errors
- HTTP + result.getStatusCode() + when fetching + result.ge
- HTTP + result.getStatusCode() + when fetching + url
- HTTP + code + when fetching + pageUrl
- HTTP ${code} when fetching ${pageUrl}
- 10000
AI-assisted analysis of alibaba/nacos@9b989acdf1 (2026-08-14).
Data as JSON: /api/errors/a497891f27071b32.
Report an issue: GitHub.