iflytek/astron-agent · warning · BusinessException

8132

8132

Error message

workflow.artifact.content.type.mismatch

What it means

Thrown when the multipart request's declared Content-Type header is active content (HTML/JS/SVG/XHTML) or, if non-blank and not application/octet-stream, does not belong to the allowed media-type set for the file's extension. This is a first-line sniff check on the client-declared type, done before any content inspection. It prevents browsers/clients from dressing up active payloads as innocuous extensions.

Solutions

  1. Fix the client or upload code so the declared Content-Type matches the file's actual type and is in the allowed set for that extension (see MEDIA_TYPES_BY_EXTENSION).
  2. If the client cannot know the type, send Content-Type: application/octet-stream, which the validator deliberately tolerates and replaces with the Tika-detected type.
  3. Verify no middleware (gateway, WAF, antivirus proxy) is rewriting the Content-Type header of multipart parts.

Example fix

// before: client sends wrong type for a .md file
Content-Type: text/html
// after
Content-Type: text/markdown  (or application/octet-stream)
Defensive patterns

Strategy: validation

Validate before calling

String declared = StringUtils.lowerCase(StringUtils.substringBefore(file.getContentType(), ";")).trim();
boolean ok = declared.isEmpty() || declared.equals("application/octet-stream")
        || allowedMediaTypesForExtension(ext).contains(declared);
if (!ok) { /* reject before validate() */ }

Try / catch

try { validator.validate(file); } catch (BusinessException e) { /* map WORKFLOW_ARTIFACT_CONTENT_TYPE_MISMATCH to a 'declared Content-Type not allowed for this extension' response */ }

Prevention

When it happens

Trigger: validate() called where file.getContentType() returns e.g. text/html, image/svg+xml, application/javascript, text/javascript, or application/xhtml+xml; or a concrete non-octet-stream type not in MEDIA_TYPES_BY_EXTENSION.get(extension), e.g. a .txt upload declaring Content-Type: text/csv-x, or a .pdf upload declaring image/png.

Common situations: HTTP clients mislabeling uploads (wrong/bogus Content-Type header); proxies or gateways rewriting Content-Type; a generic 'application/octet-stream' is tolerated but a wrong specific type is not; Spring's multipart parsing propagating the client header verbatim.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


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

Appendix: source

Thrown at console/backend/toolkit/src/main/java/com/iflytek/astron/console/toolkit/service/workflow/WorkflowArtifactFileValidator.java:151

        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);
        }
        if (ACTIVE_CONTENT_TYPES.contains(detectedType)
                || !MEDIA_TYPES_BY_EXTENSION.get(extension).contains(detectedType)) {
            throw new BusinessException(ResponseEnum.WORKFLOW_ARTIFACT_CONTENT_TYPE_MISMATCH);
        }
        return new ValidatedArtifact(fileName, detectedType);
    }

View on GitHub (pinned to 5e758547a8)