jdx/mise · error

{} has no value

Error message

{} has no value

What it means

On the write path, after --prompt/--stdin processing, every variable must carry a value before it can be encrypted. This is the --age-encrypt branch: create_age_directive() needs plaintext to encrypt to the age recipients, so a variable that still has value None bails '{key} has no value'. The single-bare-key read shortcut only applies without --prompt/--stdin, so multiple bare keys or keys skipped by prompting fall through to here.

Source

Thrown at src/cli/set.rs:218

                Settings::get().ensure_experimental("age encryption")?;
                // Collect recipients once before the loop to avoid repeated I/O
                let recipients = self.collect_age_recipients().await?;
                for ev in env_vars {
                    match ev.value {
                        Some(value) => {
                            let age_directive =
                                agecrypt::create_age_directive(ev.key.clone(), &value, &recipients)
                                    .await?;
                            if let crate::config::env_directive::EnvDirective::Age {
                                value: encrypted_value,
                                format,
                                ..
                            } = age_directive
                            {
                                mise_toml.update_env_age(&ev.key, &encrypted_value, format)?;
                            }
                        }
                        None => bail!("{} has no value", ev.key),
                    }
                }
            } else {
                for ev in env_vars {
                    match ev.value {
                        Some(value) => mise_toml.update_env(&ev.key, value)?,
                        None => bail!("{} has no value", ev.key),
                    }
                }
            }
        }
        mise_toml.save()
    }

    async fn complete(&self) -> Result<()> {
        let config = Config::get().await?;
        for ev in self.cur_env(&config).await? {
            println!("{}", ev.key);

View on GitHub (pinned to 6f52dcdf99)

Solutions

  1. Provide values inline for every key: `mise set --age-encrypt FOO=secret BAR=secret2`
  2. Or add --prompt so bare keys are prompted (and masked) interactively: `mise set --age-encrypt --prompt FOO BAR`
  3. Query values one key at a time: `mise set FOO` (single bare key is the read form)

Example fix

# before
mise set --age-encrypt --age-recipient age1... API_TOKEN DB_PASSWORD   # API_TOKEN has no value

# after
mise set --age-encrypt --age-recipient age1... API_TOKEN=xxx DB_TOKEN=yyy
# or be prompted with masked input:
mise set --age-encrypt --prompt API_TOKEN DB_TOKEN
Defensive patterns

Strategy: validation

Validate before calling

# ensure every variable has a value before encrypting
for kv in "$@"; do
  case "$kv" in
    *=*) ;;
    *) echo "$kv has no value; use KEY=VALUE or --prompt" >&2; exit 2;;
  esac
done
mise set --age-encrypt --age-recipient "$AGE_RECIPIENT" "$@"

Type guard

all_keyed() { for a in "$@"; do case "$a" in *=*) ;; *) return 1;; esac; done; return 0; }

Try / catch

Catch '{key} has no value' and re-run the same command with --prompt so the operator supplies the missing values interactively (masked for age).

Prevention

When it happens

Trigger: Running `mise set --age-encrypt FOO BAR` (two bare keys — only a single bare key takes the read path), or mixing forms like `mise set --age-encrypt FOO BAR=baz` where FOO never receives a value.

Common situations: Trying to encrypt several variables in one command while assuming bare keys would be read interactively without --prompt; mixing already-valued and bare keys in a single invocation.

Related errors


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