iflytek/astron-agent · error · BusinessException

REPO_KNOWLEDGE_DOWNLOAD_FAILED

REPO_KNOWLEDGE_DOWNLOAD_FAILED

Error message

ResponseEnum.REPO_KNOWLEDGE_DOWNLOAD_FAILED

What it means

BusinessException REPO_KNOWLEDGE_DOWNLOAD_FAILED thrown by downloadKnowLedgeData when the RestTemplate GET of the knowledgeUrl does not return HTTP 200. The extraction service reports the parsed knowledge chunks at a URL; if downloading that result file fails, the knowledge cannot be stored and the task/file are marked failed in the surrounding catch block.

Solutions

  1. Test the URL directly (curl -I <url>) to see the actual status; 404/403 usually means an expired or wrong object-store link.
  2. Ask the extraction service to regenerate/re-upload the result and re-trigger the callback, or re-run the extraction task.
  3. Check object storage (MinIO/S3) availability and credential validity on the box running this service.
  4. Consider adding retry with backoff around the download for transient 5xx, and verify proxy settings if the URL is external.

Example fix

// before
ResponseEntity<String> forEntity = restTemplate.getForEntity(url, String.class);
if (forEntity.getStatusCode() != HttpStatus.OK) {
    throw new BusinessException(ResponseEnum.REPO_KNOWLEDGE_DOWNLOAD_FAILED);
}
// after (retry transient failures)
ResponseEntity<String> forEntity = null;
for (int i = 0; i < 3; i++) {
    try {
        forEntity = restTemplate.getForEntity(url, String.class);
        if (forEntity.getStatusCode() == HttpStatus.OK) break;
    } catch (RestClientException e) {
        log.warn("download attempt {} failed: {}", i + 1, e.getMessage());
    }
}
if (forEntity == null || forEntity.getStatusCode() != HttpStatus.OK) {
    throw new BusinessException(ResponseEnum.REPO_KNOWLEDGE_DOWNLOAD_FAILED);
}
Defensive patterns

Strategy: retry

Validate before calling

// preflight before trusting the callback
HttpURLConnection c = (HttpURLConnection) new URL(url).openConnection();
c.setRequestMethod("HEAD");
if (c.getResponseCode() != 200) { requestFreshResultUrl(taskId); }

Try / catch

try { downloadKnowLedgeData(url, task, true, null); } catch (BusinessException | RestClientException e) { log.error("knowledge download failed: {}", e.getMessage()); markTaskFailed(task, e.getMessage()); }

Prevention

When it happens

Trigger: restTemplate.getForEntity(url, String.class) returning a non-OK status (403 signature/permission expired on object storage, 404 the result file was deleted or the URL expired, 5xx from the storage/extract service). Note RestTemplate throws HttpClientErrorException for 4xx before the status check — the explicit check mostly catches non-2xx responses configured not to throw.

Common situations: Presigned/knowledgeUrl expired between extraction completion and callback processing. Object storage (MinIO/S3) credentials or bucket policy changed. Upstream extractor wrote the result to a different location than the URL claims. Network/proxy blocking the internal download.

Related errors


AI-assisted analysis of iflytek/astron-agent@5e758547a8 (2026-09-12). Data as JSON: /api/errors/2bee3986f02ded9c. Report an issue: GitHub.

Appendix: source

Thrown at console/backend/toolkit/src/main/java/com/iflytek/astron/console/toolkit/service/repo/KnowledgeService.java:1382

            extractKnowledgeTask.setUpdateTime(timestamp);
            extractKnowledgeTaskService.updateById(extractKnowledgeTask);

            fileInfoV2.setStatus(ProjectContent.FILE_PARSE_FAILED);
            fileInfoV2.setReason(errMsg);
            fileInfoV2.setUpdateTime(timestamp);
            fileInfoV2Service.updateById(fileInfoV2);
            return;
        }

        Repo repo = repoService.getById(fileInfoV2.getRepoId());


        String entityBody = null;
        try {
            RestTemplate restTemplate = new RestTemplate();
            ResponseEntity<String> forEntity = restTemplate.getForEntity(url, String.class);
            if (forEntity.getStatusCode() != HttpStatus.OK) {
                throw new BusinessException(ResponseEnum.REPO_KNOWLEDGE_DOWNLOAD_FAILED);
            }
            entityBody = forEntity.getBody();
            JSONArray jsonArray = JSON.parseArray(entityBody);
            List<ChunkInfo> chunkInfos = null;
            if (repo.getEnableAudit()) {
                if (jsonArray != null) {
                    chunkInfos = jsonArray.toJavaList(ChunkInfo.class);
                }
            }
            this.storagePreviewKnowledge(fileInfoV2.getUuid(), fileInfoV2.getId(), chunkInfos);

            extractKnowledgeTask.setStatus(1);
            extractKnowledgeTask.setUpdateTime(timestamp);
            extractKnowledgeTaskService.updateById(extractKnowledgeTask);

            fileInfoV2.setStatus(ProjectContent.FILE_PARSE_SUCCESSED);
            fileInfoV2.setReason(null);
            fileInfoV2.setUpdateTime(timestamp);

View on GitHub (pinned to 5e758547a8)