{"record":{"id":"74c6b5e05a97895b","repo":"jdx/mise","slug":"task-action-manifest-has-an-invalid-identity","errorCode":null,"errorMessage":"task action manifest has an invalid identity","messagePattern":"task action manifest has an invalid identity","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/mise-cache-core/src/agent.rs","lineNumber":1822,"sourceCode":"    prediction.action.validate()?;\n    if prediction.adapter.is_empty()\n        || !prediction\n            .adapter\n            .bytes()\n            .all(|byte| byte.is_ascii_alphanumeric() || matches!(byte, b'-' | b'_'))\n    {\n        bail!(\"invalid action prediction adapter\");\n    }\n    if prediction.payload.len() > MAX_ACTION_PREDICTION_PAYLOAD {\n        bail!(\"action prediction payload is too large\");\n    }\n    serde_json::from_str::<serde_json::Value>(&prediction.payload)?;\n    Ok(())\n}\n\nfn validate_task_manifest(manifest: &TaskActionManifest, task: &str) -> Result<()> {\n    if manifest.version != TASK_ACTION_MANIFEST_VERSION || manifest.task != task {\n        bail!(\"task action manifest has an invalid identity\");\n    }\n    if manifest.predictions.len() > MAX_TASK_ACTION_PREDICTIONS {\n        bail!(\"task action manifest contains too many predictions\");\n    }\n    let mut invocations = BTreeMap::new();\n    for prediction in &manifest.predictions {\n        validate_action_prediction(prediction)?;\n        if invocations.insert(&prediction.invocation, ()).is_some() {\n            bail!(\"task action manifest contains duplicate predictions\");\n        }\n    }\n    Ok(())\n}\n\nfn merge_task_manifests(\n    task: &str,\n    base: Option<TaskActionManifest>,\n    update: TaskActionManifest,","sourceCodeStart":1804,"sourceCodeEnd":1840,"githubUrl":"https://github.com/jdx/mise/blob/6f52dcdf99e282ef7a7db68c81301fa4618d0f79/crates/mise-cache-core/src/agent.rs#L1804-L1840","documentation":"Thrown by validate_task_manifest (crates/mise-cache-core/src/agent.rs:1822) when a TaskActionManifest's identity check fails: manifest.version != TASK_ACTION_MANIFEST_VERSION (currently 1) OR manifest.task != the task name the caller passed in. The manifest must declare both the schema version it was written for and the exact task it belongs to; a mismatch means the file is stale, corrupted, or was moved to a different task.","triggerScenarios":"Calling merge_task_manifests(task, base, update) (agent.rs:1836) or any load path that validates a manifest against a task name, where update.version != 1 or update.task != task. Typical: renaming a mise task without invalidating its manifest file, or a manifest written by an older/newer mise-cache-core with a different TASK_ACTION_MANIFEST_VERSION.","commonSituations":"Task rename in mise.toml while the on-disk or remote manifest still carries the old task string; mise upgrade changing the manifest schema version; manifests copied between projects; hand-edited manifest JSON with a typo'd task field.","solutions":["If the task was renamed, delete/regenerate the cached manifest for the old task name so it is rebuilt with the new identity","If version mismatched after upgrading mise, clear the task action manifest cache once — manifests are re-created under the new version","Verify the manifest JSON actually declares the same task string (exact match, no path prefixes or whitespace differences) that the caller passes","If you write manifests programmatically, always set version: TASK_ACTION_MANIFEST_VERSION (1) and the canonical task name"],"exampleFix":"// before\nlet manifest = TaskActionManifest { version: 2, task: \"build\".into(), predictions }; // version 2 rejected by client on v1\n\n// after\nlet manifest = TaskActionManifest { version: TASK_ACTION_MANIFEST_VERSION, task: task.to_string(), predictions };","handlingStrategy":"validation","validationCode":"fn manifest_identity_ok(manifest: &TaskActionManifest, task: &str) -> bool {\n    manifest.version == 1 && manifest.task == task\n}\n// gate before merge/load:\nif !manifest_identity_ok(&manifest, task) {\n    // stale or foreign manifest: discard and regenerate\n}","typeGuard":"fn is_current_manifest(m: &TaskActionManifest, task: &str) -> bool {\n    m.version == TASK_ACTION_MANIFEST_VERSION && m.task == task\n}","tryCatchPattern":"match load_manifest(task) {\n    Err(e) if e.to_string().contains(\"invalid identity\") => regenerate_manifest(task), // treat as cache miss\n    other => other,\n}","preventionTips":["Treat identity mismatches as cache misses: drop the manifest and rebuild rather than surfacing the error","Use the canonical task name from the same source both when writing and validating manifests","Bump-and-clear cached manifests whenever TASK_ACTION_MANIFEST_VERSION changes in your fork"],"tags":["mise","cache","validation","version-mismatch","task-manifest"],"backgroundTag":"schema-version-mismatch","analyzedSha":"6f52dcdf99e282ef7a7db68c81301fa4618d0f79","analyzedAt":"2026-08-22T10:14:23.840Z","schemaVersion":2},"datasetVersion":"2026-08-23T13:39:53.451Z"}