{"record":{"id":"354c7ffde6a2f777","repo":"iflytek/astron-agent","slug":"size-limit-is-invalid","errorCode":null,"errorMessage":" size limit is invalid","messagePattern":" size limit is invalid","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"console/backend/hub/src/main/java/com/iflytek/astron/console/hub/service/chat/springai/SkillRuntimeToolService.java","lineNumber":152,"sourceCode":"            throws IOException {\n        validateLimit(limit, description);\n        long contentLength = body.contentLength();\n        if (contentLength > limit) {\n            throw new IOException(description + \" exceeds size limit\");\n        }\n        int readLimit = Math.toIntExact(limit + 1);\n        try (InputStream input = body.byteStream()) {\n            byte[] bytes = input.readNBytes(readLimit);\n            if (bytes.length > limit) {\n                throw new IOException(description + \" exceeds size limit\");\n            }\n            return bytes;\n        }\n    }\n\n    private void validateLimit(long limit, String description) throws IOException {\n        if (limit < 1 || limit > MAX_CONFIGURABLE_RESPONSE_BYTES) {\n            throw new IOException(description + \" size limit is invalid\");\n        }\n    }\n\n    private String decodeText(byte[] bytes, ResponseBody body) {\n        MediaType contentType = body.contentType();\n        if (contentType == null) {\n            return new String(bytes, StandardCharsets.UTF_8);\n        }\n        Charset configuredCharset = contentType.charset();\n        Charset charset = configuredCharset == null ? StandardCharsets.UTF_8 : configuredCharset;\n        return new String(bytes, charset);\n    }\n\n    private void validateResourceUrl(String url) throws IOException {\n        final URI candidate;\n        final URI configuredOrigin;\n        try {\n            candidate = new URI(StringUtils.trimToEmpty(url));","sourceCodeStart":134,"sourceCodeEnd":170,"githubUrl":"https://github.com/iflytek/astron-agent/blob/5e758547a83371a5a4b29dadf4ac03e8dd527635/console/backend/hub/src/main/java/com/iflytek/astron/console/hub/service/chat/springai/SkillRuntimeToolService.java#L134-L170","documentation":"validateLimit guards the configurable size limits used by executeSandbox, downloadText, and readBounded. The configured limit (maxSandboxResponseBytes or maxResourceBytes, both Spring @Value properties) must be between 1 and MAX_CONFIGURABLE_RESPONSE_BYTES (20 MiB). When the property is misconfigured to 0, a negative number, or something above 20 MiB, the service refuses to start the operation and throws this IOException instead of downloading/reading anything.","triggerScenarios":"Calling executeSandbox when skill.runtime.max-sandbox-response-bytes is <=0 or >20971520; calling downloadText when skill.runtime.max-resource-bytes is <=0 or >20971520; readBounded re-validates on every read so any invalid property value surfaces here before the HTTP body is consumed.","commonSituations":"Operator sets skill.runtime.max-resource-bytes=0 thinking 0 means unlimited; a typo like 30m or a raw byte value above 20971520 (20 MiB) is put in application.yml; an environment variable override injects an empty or negative value; defaults removed from config leaving an unparseable/negative value.","solutions":["Set skill.runtime.max-resource-bytes and skill.runtime.max-sandbox-response-bytes to values in the range 1..20971520 in application.yml or environment.","Check for conflicting overrides (env vars, profile-specific yml, config server) that push the value outside the allowed range or make it 0/negative.","If a larger limit is genuinely required, raise the constant MAX_CONFIGURABLE_RESPONSE_BYTES in SkillRuntimeToolService.java deliberately, understanding it caps memory per download.","Log the effective property values at startup to catch misconfiguration before a request hits the validation."],"exampleFix":"// before (application.yml)\nskill:\n  runtime:\n    max-resource-bytes: 0\n// after\nskill:\n  runtime:\n    max-resource-bytes: 1048576   # 1 MiB, within 1..20971520","handlingStrategy":"validation","validationCode":"long MAX = 20L * 1024 * 1024;\nboolean limitOk = maxResourceBytes >= 1 && maxResourceBytes <= MAX;\nif (!limitOk) throw new IllegalStateException(\n    \"skill.runtime.max-resource-bytes must be in [1, \" + MAX + \"], got: \" + maxResourceBytes);","typeGuard":null,"tryCatchPattern":"try {\n    String text = skillRuntimeToolService.downloadText(url);\n} catch (IOException e) {\n    if (e.getMessage() != null && e.getMessage().endsWith(\"size limit is invalid\")) {\n        // misconfigured limit: fail fast with config context\n        throw new ConfigurationException(\"Check skill.runtime.*-bytes settings\", e);\n    }\n    throw e;\n}","preventionTips":["Add a @PostConstruct startup check that asserts both size-limit properties are within 1..20971520.","Never configure 0 to mean unlimited — pick a large valid value instead.","Use Spring's configuration property binding with validation annotations (@Positive, @Max) so bad values fail at boot."],"tags":["configuration","validation","io","java","spring"],"backgroundTag":"value-out-of-range","analyzedSha":"5e758547a83371a5a4b29dadf4ac03e8dd527635","analyzedAt":"2026-09-12T08:03:51.356Z","contentChangedAt":"2026-09-12T08:03:51.356Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}