{"record":{"id":"c09c8e3f19ec9ded","repo":"iflytek/astron-agent","slug":"sandbox-exec-failed-http","errorCode":null,"errorMessage":"sandbox-exec failed: HTTP ","messagePattern":"sandbox-exec failed: HTTP ","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":95,"sourceCode":"        String signature = runtimeCredentialTokenProvider.signExecutionRequest(\n                timestamp, requestBody);\n        Request request = new Request.Builder()\n                .url(url)\n                .post(RequestBody.create(requestBody, JSON_MEDIA_TYPE))\n                .addHeader(\"Content-Type\", \"application/json\")\n                .addHeader(\n                        \"X-Skill-Sandbox-Execution-Timestamp\",\n                        String.valueOf(timestamp))\n                .addHeader(\"X-Skill-Sandbox-Execution-Signature\", signature)\n                .build();\n        OkHttpClient client = httpClient.newBuilder()\n                .callTimeout(Duration.ofSeconds(120))\n                .followRedirects(false)\n                .followSslRedirects(false)\n                .build();\n        try (Response response = client.newCall(request).execute()) {\n            if (!response.isSuccessful()) {\n                throw new IOException(\"sandbox-exec failed: HTTP \" + response.code());\n            }\n            ResponseBody respBody = response.body();\n            return respBody == null\n                    ? \"\"\n                    : decodeText(\n                            readBounded(respBody, maxSandboxResponseBytes, \"Sandbox response\"),\n                            respBody);\n        }\n    }\n\n    /** Download a text resource (SKILL.md or a referenced file) from a presigned URL. */\n    public String downloadText(String url) throws IOException {\n        validateLimit(maxResourceBytes, \"Skill resource\");\n        validateResourceUrl(url);\n        Request request;\n        try {\n            request = new Request.Builder().url(url).get().build();\n        } catch (IllegalArgumentException exception) {","sourceCodeStart":77,"sourceCodeEnd":113,"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#L77-L113","documentation":"executeSandbox posts to the sandbox-exec HTTP endpoint using an OkHttp client configured with no redirects and a 120s call timeout. When the sandbox service answers with a non-2xx status, the method throws an IOException with only the status code (never the response body, deliberately avoiding leaking sensitive details). It means the sandbox execution request was rejected or failed server-side.","triggerScenarios":"The sandbox service returns HTTP 4xx/5xx to executeSandbox — e.g. sandbox container not running, auth rejection, payload rejected, or gateway 502/503 — while a skill is being run via runSkill.","commonSituations":"Sandbox deployment down or misconfigured (wrong sandbox URL in config); sandbox returned 401/403 due to expired credentials; 413 for oversized skill payloads; 504 when skill execution exceeded sandbox limits; network proxy or service mesh blocking the call.","solutions":["Check that the sandbox service is up and reachable at the configured URL (curl the health endpoint).","Inspect sandbox service logs for the corresponding request to learn the real error (the exception intentionally hides the body).","Verify sandbox credentials/auth and that the request payload meets sandbox input constraints.","Check gateway/proxy settings for timeouts (120s callTimeout) and body-size limits between console backend and sandbox."],"exampleFix":"// before\n// executeSandbox throws bare \"sandbox-exec failed: HTTP 502\"\ntry {\n    String out = skillRuntimeToolService.runSkill(skillId, input);\n} catch (IOException e) {\n    // e.getMessage() only has the status code\n}\n// after\ntry {\n    String out = skillRuntimeToolService.runSkill(skillId, input);\n} catch (IOException e) {\n    log.error(\"sandbox exec failed; verify sandbox service health/config\", e);\n    throw new BusinessException(ResponseEnum.SANDBOX_EXEC_FAILED); // user-facing message\n}","handlingStrategy":"try-catch","validationCode":"boolean sandboxHealthy = httpGet(sandboxUrl + \"/health\").code() == 200;\nif (!sandboxHealthy) {\n    throw new IllegalStateException(\"Sandbox service unavailable\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    String result = skillRuntimeToolService.runSkill(skillId, input);\n} catch (IOException e) {\n    if (e.getMessage() != null && e.getMessage().startsWith(\"sandbox-exec failed: HTTP\")) {\n        int status = Integer.parseInt(e.getMessage().substring(e.getMessage().lastIndexOf(' ') + 1));\n        // retry on 5xx only; surface 4xx to the user\n    }\n}","preventionTips":["Health-check the sandbox endpoint before issuing skill executions.","Pin and monitor sandbox service availability in deployment checks.","Keep sandbox payloads within documented size limits.","Alert on sandbox 5xx rates from the sandbox service's own metrics."],"tags":["http","network","java","sandbox","okhttp"],"backgroundTag":"http-error-response","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"}