{"record":{"id":"4e85d932f10a30a1","repo":"jdx/mise","slug":"stdin-requires-exactly-one-environment-variable","errorCode":null,"errorMessage":"--stdin requires exactly one environment variable key","messagePattern":"--stdin requires exactly one environment variable key","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/cli/set.rs","lineNumber":179,"sourceCode":"            // Prompt for values if requested\n            if self.prompt {\n                let theme = crate::ui::theme::get_theme();\n                for ev in &mut env_vars {\n                    if ev.value.is_none() {\n                        let prompt_msg = format!(\"Enter value for {}\", ev.key);\n                        let value = Input::new(&prompt_msg)\n                            .password(self.age_encrypt) // Mask input if encrypting\n                            .theme(&theme)\n                            .run()?;\n                        ev.value = Some(value);\n                    }\n                }\n            }\n\n            // Read value from stdin if requested\n            if self.stdin {\n                if env_vars.len() != 1 {\n                    bail!(\"--stdin requires exactly one environment variable key\");\n                }\n                let ev = &mut env_vars[0];\n                if ev.value.is_some() {\n                    bail!(\n                        \"--stdin reads the value from stdin; do not provide a value with KEY=VALUE syntax\"\n                    );\n                }\n                let mut value = String::new();\n                std::io::stdin().read_to_string(&mut value)?;\n                // Strip a single trailing newline (matches `gh secret set` behavior)\n                if value.ends_with(\"\\r\\n\") {\n                    value.truncate(value.len() - 2);\n                } else if value.ends_with('\\n') {\n                    value.truncate(value.len() - 1);\n                }\n                ev.value = Some(value);\n            }\n","sourceCodeStart":161,"sourceCodeEnd":197,"githubUrl":"https://github.com/jdx/mise/blob/6f52dcdf99e282ef7a7db68c81301fa4618d0f79/src/cli/set.rs#L161-L197","documentation":"`mise set --stdin` reads one variable's value from stdin (like `gh secret set`) and therefore accepts exactly one environment variable key. The code checks env_vars.len() != 1 after prompt handling and bails, so passing two or more keys (or relying on stdin while naming multiple variables) is rejected before anything is read.","triggerScenarios":"Running `mise set --stdin FOO BAR`, or `echo val | mise set --stdin A B`, i.e. any --stdin invocation whose positional arguments are not exactly one bare key.","commonSituations":"Scripts trying to set several secrets in one pass through a single pipe; misunderstanding the gh-secret-style one-key-per-invocation contract.","solutions":["Pipe one key at a time: `printf '%s' \"$val\" | mise set --stdin FOO`","Loop for multiple variables in shell: `while read -r key val; do printf '%s' \"$val\" | mise set --stdin \"$key\"; done < secrets.tsv`","For non-secret bulk sets, skip stdin: `mise set FOO=1 BAR=2`"],"exampleFix":"# before\necho secret | mise set --stdin API_TOKEN DB_PASSWORD   # --stdin requires exactly one environment variable key\n\n# after\nprintf '%s' \"$token\" | mise set --stdin API_TOKEN\nprintf '%s' \"$pass\"  | mise set --stdin DB_PASSWORD","handlingStrategy":"validation","validationCode":"# enforce the one-key contract before piping\nset -euo pipefail\n[ \"$#\" -eq 1 ] || { echo 'usage: set_secret KEY  (value on stdin)' >&2; exit 2; }\nprintf '%s' \"$secret\" | mise set --stdin \"$1\"","typeGuard":"is_single_bare_key() { [ \"$#\" -eq 1 ] && case \"$1\" in *=*) return 1;; *) return 0;; esac; }","tryCatchPattern":"Catch and surface the message directly to the operator — it is a usage contract violation; fix the call site (one key per --stdin invocation) instead of retrying.","preventionTips":["Model mise set --stdin after `gh secret set`: exactly one key per pipe","Loop per variable when setting multiple secrets from a file","Reserve --stdin for secrets; use KEY=VALUE form for bulk plain sets"],"tags":["cli","stdin","arguments","env","mise"],"backgroundTag":"invalid-cli-argument","analyzedSha":"6f52dcdf99e282ef7a7db68c81301fa4618d0f79","analyzedAt":"2026-08-22T10:14:23.840Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}