xai-org/x-algorithm · error · PermanentAisFailure

AIS {action_name} raised deterministic {class}: {detail}

Error message

AIS {action_name} raised deterministic {class}: {detail}

What it means

AIS raised an exception whose class is in DETERMINISTIC_AIS_EXCEPTION_CLASSES, meaning the same request will always fail the same way. It is wrapped in PermanentAisFailure so callers do not waste retries on it.

Source

Thrown at abuse-enforcement-service/service-lib/src/service.rs:941

pub fn classify_ais_failure(action_name: &str, message: &str, resp: &Value) -> anyhow::Error {
    if resp.pointer("/success/outcome/failure").is_some()
        || resp.pointer("/outcome/failure").is_some()
    {
        return anyhow::Error::new(PermanentAisFailure(format!(
            "AIS rejected {action_name}: {message}"
        )));
    }
    if let Some(class) = resp
        .pointer("/aisException/underlyingDetails/exceptionClass")
        .and_then(Value::as_str)
        && DETERMINISTIC_AIS_EXCEPTION_CLASSES.contains(&class)
    {
        let detail = resp
            .pointer("/aisException/underlyingDetails/message")
            .and_then(Value::as_str)
            .unwrap_or("");
        return anyhow::Error::new(PermanentAisFailure(format!(
            "AIS {action_name} raised deterministic {class}: {detail}"
        )));
    }
    anyhow::anyhow!("AIS failure on {action_name}: {message}")
}

pub fn parse_ais_response(user_id: i64, resp: &Value) -> UserActionResult {
    let outcome_success = resp
        .pointer("/success/outcome/success")
        .or_else(|| resp.pointer("/outcome/success"));
    if let Some(action_id) = outcome_success
        .and_then(|s| s.get("actionId"))
        .and_then(|id| id.as_str())
    {
        UserActionResult {
            user_id,
            success: true,
            message: format!("actionId={action_id}"),

View on GitHub (pinned to 24c60942c5)

Solutions

  1. Read the {class} and {detail} to identify the deterministic cause
  2. Correct the request payload that triggers the exception
  3. If the class is legitimately transient-looking, verify it belongs in DETERMINISTIC_AIS_EXCEPTION_CLASSES and file an issue if misclassified
  4. Suppress/requeue the affected item rather than retrying
Defensive patterns

Strategy: try-catch

Try / catch

Downcast the anyhow error to PermanentAisFailure; route to a dead-letter queue instead of retry loops.

Prevention

When it happens

Trigger: AIS response contains /aisException/underlyingDetails/exceptionClass matching a known deterministic class (e.g. validation or invalid-argument style exceptions), with the detail taken from underlyingDetails/message.

Common situations: Schema or enum value mismatch in the enforcement request; AIS version change introducing new deterministic exception classes; bad input data (empty strings, out-of-range params).

Related errors


AI-assisted analysis of xai-org/x-algorithm@24c60942c5 (2026-08-28). Data as JSON: /api/errors/462c54f54a0d7e75. Report an issue: GitHub.