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
- Read the embedded cause in the message ('assemble requestHeader error: ...') to identify the failing signing step.
- Verify the API key, secret, and host used by CoreSystemService are configured and non-null.
- Confirm the request URL/host is fully formed before header assembly (no null path or query).
- 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
- Check apiKey/secret/host configuration at service startup, not per-request.
- Use explicit charset (UTF-8) for secret bytes to avoid platform-dependent failures.
- Unit-test header assembly whenever the signing algorithm or config schema changes.
- Keep the digest algorithm name in a validated constant.
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
- MODEL_APIKEY_ERROR
- Login successful but JSESSIONID cookie not found
- FILE_INVALID_TYPE_ERROR
- tenant verify app auth request failed, status=
- 上传失败
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)