iflytek/astron-agent · warning · BusinessException
8131
8131
Error message
workflow.artifact.file.type.not.allowed
What it means
WorkflowArtifactFileValidator.validate rejects artifact uploads whose filename extension is missing, is not in the configured allowed-extension list (SkillSandboxArtifactProperties.artifactAllowedExtensions), or has no registered media-type mapping in MEDIA_TYPES_BY_EXTENSION. The platform only accepts artifacts with a known, permitted extension (txt, md, csv, json, pdf, images, Office documents, zip). This is a policy error, not corruption: the file itself was never inspected.
Solutions
- Check the uploaded file's extension and rename/save it with a supported extension (txt, md, csv, json, pdf, png, jpg, jpeg, gif, webp, doc, xls, ppt, docx, xlsx, pptx, zip).
- Verify the workflow artifact allowed-extensions configuration (SkillSandboxArtifactProperties.artifactAllowedExtensions) includes the extension you need; add it if missing.
- If adding a genuinely new type, also add an entry to MEDIA_TYPES_BY_EXTENSION in WorkflowArtifactFileValidator — config alone is insufficient.
Example fix
// before (config omits the type) artifact.allowed-extensions=txt,md,csv,json,pdf // after artifact.allowed-extensions=txt,md,csv,json,pdf,png,docx
Defensive patterns
Strategy: validation
Validate before calling
String ext = StringUtils.lowerCase(FilenameUtils.getExtension(file.getOriginalFilename()));
Set<String> allowed = properties.getArtifactAllowedExtensions();
boolean ok = StringUtils.isNotBlank(ext) && allowed.stream().anyMatch(ext::equalsIgnoreCase);
if (!ok) { /* reject before calling validate() */ } Try / catch
try { validator.validate(file); } catch (BusinessException e) { if (e.getResponse() == ResponseEnum.WORKFLOW_ARTIFACT_FILE_TYPE_NOT_ALLOWED) { /* return 4xx with allowed-extension hint to the client */ } throw e; } Prevention
- Validate the extension client-side against the documented allowed list before uploading.
- Keep artifactAllowedExtensions and the validator's MEDIA_TYPES_BY_EXTENSION map in sync when adding types.
- Strip client path components and send a clean filename with a real extension.
When it happens
Trigger: Calling validate() with a MultipartFile whose originalFilename has no extension (e.g. 'README'), whose extension is not present in properties.getArtifactAllowedExtensions(), or whose extension is allowed in config but absent from the validator's MEDIA_TYPES_BY_EXTENSION map (e.g. an extension added to config but unsupported in code).
Common situations: Users uploading files like .exe, .sh, .docm, or extensionless files; admins narrowing artifactAllowedExtensions so previously accepted types are now rejected; a new extension added to config without code support; clients sending filenames without extensions after path normalization strips them.
Related errors
- 8132
- LONG_CONTENT_CHAT_ID_ERROR
- LONG_CONTENT_WRONG_BUSINESS_TYPE
- LONG_CONTENT_MISS_FILE_INFO
- LONG_CONTENT_FILE_SIZE_OUT_LIMIT
AI-assisted analysis of iflytek/astron-agent@5e758547a8 (2026-09-12).
Data as JSON: /api/errors/a73c0b5110cd553a.
Report an issue: GitHub.
Appendix: source
Thrown at console/backend/toolkit/src/main/java/com/iflytek/astron/console/toolkit/service/workflow/WorkflowArtifactFileValidator.java:143
this.properties = Objects.requireNonNull(properties);
this.ooxmlResourceLimits = Objects.requireNonNull(ooxmlResourceLimits);
}
public ValidatedArtifact validate(MultipartFile file) {
if (file == null || file.isEmpty() || StringUtils.isBlank(file.getOriginalFilename())) {
throw new BusinessException(ResponseEnum.PARAM_ERROR);
}
if (file.getSize() <= 0 || file.getSize() > properties.getArtifactMaxFileSize().toBytes()) {
throw new BusinessException(ResponseEnum.WORKFLOW_ARTIFACT_FILE_TOO_LARGE);
}
String fileName = normalizeFileName(file.getOriginalFilename());
String extension = StringUtils.lowerCase(FilenameUtils.getExtension(fileName), Locale.ROOT);
Set<String> configuredExtensions = properties.getArtifactAllowedExtensions();
if (StringUtils.isBlank(extension)
|| configuredExtensions.stream().noneMatch(extension::equalsIgnoreCase)
|| !MEDIA_TYPES_BY_EXTENSION.containsKey(extension)) {
throw new BusinessException(ResponseEnum.WORKFLOW_ARTIFACT_FILE_TYPE_NOT_ALLOWED);
}
String declaredType = normalizeMediaType(file.getContentType());
if (ACTIVE_CONTENT_TYPES.contains(declaredType)
|| (!StringUtils.isBlank(declaredType)
&& !OCTET_STREAM.equals(declaredType)
&& !MEDIA_TYPES_BY_EXTENSION.get(extension).contains(declaredType))) {
throw new BusinessException(ResponseEnum.WORKFLOW_ARTIFACT_CONTENT_TYPE_MISMATCH);
}
// Preflight Office containers before the general detector. OOXML resource limits run
// before its POI package parse inside validateOoxmlContainer.
validateOfficeContainer(file, extension);
String detectedType;
try (InputStream input = file.getInputStream()) {
detectedType = normalizeMediaType(tika.detect(input, fileName));
} catch (IOException exception) {
throw new BusinessException(ResponseEnum.WORKFLOW_ARTIFACT_CONTENT_TYPE_MISMATCH);View on GitHub (pinned to 5e758547a8)