jdx/mise · error

deps output rules should serialize

Error message

deps output rules should serialize

What it means

mise panics with 'deps output rules should serialize' in `output_rules_hash` when `serde_json::to_string` fails to serialize the dependency provider's configured output directory and rules. Both are plain serializable config types, so serialization should always succeed; this expect documents that any failure is an unrecoverable programming error. The hash gives output rules a stable identity used to detect whether declared rules changed versus glob matches appearing/disappearing.

Source

Thrown at src/deps/providers/mod.rs:107

            .map(|patterns| self.resolve_path_patterns(patterns, true))
            .unwrap_or(default)
    }

    pub(crate) fn optional_outputs(&self, default: Vec<PathBuf>) -> Vec<PathBuf> {
        if self.config.outputs.is_some() {
            vec![]
        } else {
            default
        }
    }

    /// Returns a stable identity for the configured output rules without
    /// expanding glob matches. This distinguishes omitted defaults, explicit
    /// replacements, and an explicit empty list while keeping the identity
    /// unchanged when files matching a glob are added or removed.
    pub(crate) fn output_rules_hash(&self) -> String {
        let rules = serde_json::to_string(&(&self.config.dir, &self.config.outputs))
            .expect("deps output rules should serialize");
        crate::hash::hash_blake3_to_str(&rules)
    }

    /// The configured `run` override, or `program` invoked with `args`.
    /// `description` only applies when the rule doesn't configure one.
    pub(crate) fn install_command(
        &self,
        program: &str,
        args: &[&str],
        description: &str,
    ) -> Result<DepsCommand> {
        if let Some(run) = &self.config.run {
            return DepsCommand::from_string(run, &self.project_root, &self.config);
        }
        let description = self
            .config
            .description
            .clone()

View on GitHub (pinned to afd2eddd3a)

Solutions

  1. Ensure `dir` and every `outputs` rule variant derive/implement `serde::Serialize` with JSON-compatible types
  2. Avoid non-string map keys or custom serializers that can fail in the rule types
  3. Match on the serialization error and wrap it in a user-facing error instead of `expect` if new fallible types are unavoidable
  4. Re-run `output_rules_hash_tracks_declared_rules_not_glob_matches` after changing the rule types

Example fix

// before
#[derive(Debug)]
pub struct OutputRule { pub glob: String, pub action: Action }
// after
#[derive(Debug, serde::Serialize)]
pub struct OutputRule { pub glob: String, pub action: Action }
Defensive patterns

Strategy: validation

Validate before calling

serde_json::to_string(&(&cfg.dir, &cfg.outputs)).expect("output rules must be JSON-serializable"); // run in a unit test

Type guard

fn serializable<T: serde::Serialize>(v: &T) -> bool { serde_json::to_string(v).is_ok() }

Try / catch

match serde_json::to_string(&value) { Ok(s) => s, Err(e) => return Err(e.into()) }

Prevention

When it happens

Trigger: Adding a non-serializable type (e.g. a map with non-string keys, an untagged enum variant, or a type missing `Serialize`) to `DepProviderConfig::dir` or `outputs` so `serde_json::to_string` returns an error; a serde attribute change (like `skip_serializing_if` interplay or custom serializer returning Err) on those fields.

Common situations: A contributor extends the deps provider config with a new output-rule field and forgets to derive/implement `Serialize`, or uses a type JSON cannot represent (e.g. `PathBuf` keys in a HashMap).

Understand the failure class

Background: "JSON serialization failed", "not JSON serializable", "Failed to serialize": why JSON marshaling errors happen and how to fix them — this error's family across 46 libraries.

Related errors


AI-assisted analysis of jdx/mise@afd2eddd3a (2026-09-09). Data as JSON: /api/errors/bf20bd987087f27e. Report an issue: GitHub.