iflytek/astron-agent · error · BusinessException

RESPONSE_FAILED

RESPONSE_FAILED

Error message

assemble requestHeader  error:

What it means

Thrown by CoreSystemService.assembleRequestHeader when building the signed request headers (authorization, host, date, digest) for calls to the core system API fails. Any exception in the signing/assembly path (HMAC/digest computation, date formatting, host/secret configuration) is wrapped as BusinessException(RESPONSE_FAILED) with message 'assemble requestHeader error:' + the cause.

Solutions

  1. Read the embedded cause in the message ('assemble requestHeader error: ...') to identify the failing signing step.
  2. Verify the API key, secret, and host used by CoreSystemService are configured and non-null.
  3. Confirm the request URL/host is fully formed before header assembly (no null path or query).
  4. Unit-test assembleRequestHeader directly with the current config to reproduce the digest failure in isolation.

Example fix

// before
Mac mac = Mac.getInstance("HmacSHA256");
mac.init(new SecretKeySpec(secret.getBytes(), "HmacSHA256"));
// after
if (apiKey == null || secret == null || host == null) {
    throw new BusinessException(ResponseEnum.RESPONSE_FAILED, "missing apiKey/secret/host for header signing");
}
Mac mac = Mac.getInstance("HmacSHA256");
mac.init(new SecretKeySpec(secret.getBytes(StandardCharsets.UTF_8), "HmacSHA256"));
Defensive patterns

Strategy: validation

Validate before calling

// before assembling headers
boolean canSign(String apiKey, String secret, String host) {
    return apiKey != null && !apiKey.isBlank()
        && secret != null && !secret.isBlank()
        && host != null && !host.isBlank();
}

Type guard

boolean hasSigningMaterial(Map<String, String> config) {
    return Stream.of("apiKey", "apiSecret", "host").allMatch(k -> {
        String v = config.get(k);
        return v != null && !v.isBlank();
    });
}

Try / catch

try {
    Map<String, String> header = coreSystemService.assembleRequestHeader(url, body);
} catch (BusinessException e) {
    // message contains 'assemble requestHeader  error:' + cause
    log.error("header signing failed: {}", e.getMessage());
}

Prevention

When it happens

Trigger: publish, auth, uploadFile, or batchUploadFile invokes assembleRequestHeader and the digest/signature computation throws — null API secret, bad key/secret charset, unsupported digest algorithm, or null host/url parts.

Common situations: Missing or malformed API key/secret in configuration; host or URL not set so signing input is null; JVM lacking the digest algorithm; misconfigured character encoding for the secret bytes.

Understand the failure class

Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.

Related errors


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

Appendix: source

Thrown at console/backend/toolkit/src/main/java/com/iflytek/astron/console/toolkit/service/extra/CoreSystemService.java:358

                    append(method).append(" ").append(path).append(" HTTP/1.1").append("\n").append("digest: ").append(digest);
            Charset charset = Charset.forName("UTF-8");

            // Use hmac-sha256 to calculate signature
            Mac mac = Mac.getInstance("hmacsha256");
            SecretKeySpec spec = new SecretKeySpec(apiSecret.getBytes(charset), "hmacsha256");
            mac.init(spec);
            byte[] hexDigits = mac.doFinal(builder.toString().getBytes(charset));
            String sha = Base64.getEncoder().encodeToString(hexDigits);
            // Build header
            String authorization = String.format("hmac-auth api_key=\"%s\", algorithm=\"%s\", headers=\"%s\", signature=\"%s\"", apiKey, "hmac-sha256", "host date request-line digest", sha);
            Map<String, String> header = new HashMap<String, String>();
            header.put("authorization", authorization);
            header.put("host", host);
            header.put("date", date);
            header.put("digest", digest);
            return header;
        } catch (Exception e) {
            throw new BusinessException(ResponseEnum.RESPONSE_FAILED, "assemble requestHeader  error:" + e.getMessage());
        }
    }

    /**
     * Adds workflow comparison data for protocol validation Saves comparison protocols for the
     * specified workflow and version
     *
     * @param protocol The flow protocol containing comparison data
     * @param flowId The workflow ID to add comparisons for
     * @param version The specific version of the workflow
     * @throws BusinessException if the add operation fails
     */
    public void addComparisons(FlowProtocol protocol, String flowId, String version) {
        String url = apiUrl.getWorkflow().concat(ADD_COMPARISONS_PATH);
        JSONObject jsonObject = new JSONObject()
                .fluentPut("flow_id", flowId)
                .fluentPut("version", version)
                .fluentPut("data", protocol);

View on GitHub (pinned to 5e758547a8)