jdx/mise · error

invalid action prediction adapter

Error message

invalid action prediction adapter

What it means

validate_action_prediction requires prediction.adapter to be a non-empty string of ASCII alphanumerics plus '-' and '_' only. Adapter names become part of recorded cache metadata, so free-form characters (spaces, dots, slashes, '@') are rejected.

Source

Thrown at crates/mise-cache-core/src/agent.rs:1811

        || !task
            .bytes()
            .all(|byte| byte.is_ascii_digit() || (b'a'..=b'f').contains(&byte))
    {
        bail!("invalid task action identity");
    }
    Ok(())
}

fn validate_action_prediction(prediction: &ActionPrediction) -> Result<()> {
    prediction.invocation.validate()?;
    prediction.action.validate()?;
    if prediction.adapter.is_empty()
        || !prediction
            .adapter
            .bytes()
            .all(|byte| byte.is_ascii_alphanumeric() || matches!(byte, b'-' | b'_'))
    {
        bail!("invalid action prediction adapter");
    }
    if prediction.payload.len() > MAX_ACTION_PREDICTION_PAYLOAD {
        bail!("action prediction payload is too large");
    }
    serde_json::from_str::<serde_json::Value>(&prediction.payload)?;
    Ok(())
}

fn validate_task_manifest(manifest: &TaskActionManifest, task: &str) -> Result<()> {
    if manifest.version != TASK_ACTION_MANIFEST_VERSION || manifest.task != task {
        bail!("task action manifest has an invalid identity");
    }
    if manifest.predictions.len() > MAX_TASK_ACTION_PREDICTIONS {
        bail!("task action manifest contains too many predictions");
    }
    let mut invocations = BTreeMap::new();
    for prediction in &manifest.predictions {
        validate_action_prediction(prediction)?;

View on GitHub (pinned to 6f52dcdf99)

Solutions

  1. Normalize adapter names to [A-Za-z0-9_-]+ before recording, e.g. "cargo-build" or "rustc"
  2. Reject or default empty adapter fields upstream instead of sending them

Example fix

// before
let adapter = format!("{}@{}", tool, version); // "rustc@1.80"
// after
let adapter = format!("{}-{}", tool, version).replace(|c: char| !c.is_ascii_alphanumeric() && c != '-' && c != '_', "-");
Defensive patterns

Strategy: validation

Validate before calling

fn normalize_adapter(name: &str) -> String {
    name.chars()
        .map(|c| if c.is_ascii_alphanumeric() || c == '-' || c == '_' { c } else { '-' })
        .collect()
}
let adapter = normalize_adapter(&adapter);
assert!(!adapter.is_empty());

Type guard

fn is_valid_adapter(adapter: &str) -> bool {
    !adapter.is_empty()
        && adapter.bytes().all(|b| b.is_ascii_alphanumeric() || matches!(b, b'-' | b'_'))
}

Prevention

When it happens

Trigger: Recording a prediction with adapter like "cargo build" (space), "rustc@1.80" ('@'), "go/build" (slash), or "" (empty string).

Common situations: Deriving adapter names from arbitrary CLI strings or versioned labels; empty adapter due to a missing field in generated prediction payloads.

Understand the failure class

Background: "invalid id" errors: invalid identifier format — why libraries reject IDs before lookup, and how to fix them — this error's family across 37 libraries.

Related errors


AI-assisted analysis of jdx/mise@6f52dcdf99 (2026-08-22). Data as JSON: /api/errors/24aa36d83007d892. Report an issue: GitHub.