{"record":{"id":"0d8948189b94411b","repo":"jdx/mise","slug":"bootstrap-secret-name-has-invalid-environment","errorCode":null,"errorMessage":"bootstrap secret '{name}' has invalid environment variable name '{env}'","messagePattern":"bootstrap secret '(.+?)' has invalid environment variable name '(.+?)'","errorType":"validation","errorClass":"eyre::Report","httpStatus":null,"severity":"error","filePath":"src/system/secrets.rs","lineNumber":308,"sourceCode":"    Ok(value)\n}\n\nfn declaration_from_toml(name: String, declaration: SecretTomlConfig) -> Result<SecretDeclaration> {\n    if name.is_empty()\n        || !name\n            .chars()\n            .all(|character| character.is_ascii_alphanumeric() || \"_.-\".contains(character))\n    {\n        bail!(\"invalid bootstrap secret name '{name}': use ASCII letters, digits, '.', '_' or '-'\");\n    }\n    let (env, description, allow_empty) = match declaration {\n        SecretTomlConfig::Env(env) => (env, None, false),\n        SecretTomlConfig::Options(options) => {\n            (options.env, options.description, options.allow_empty)\n        }\n    };\n    if !valid_env_name(&env) {\n        bail!(\"bootstrap secret '{name}' has invalid environment variable name '{env}'\");\n    }\n    Ok(SecretDeclaration {\n        name,\n        env,\n        description,\n        allow_empty,\n    })\n}\n\nfn valid_env_name(name: &str) -> bool {\n    let mut characters = name.chars();\n    characters\n        .next()\n        .is_some_and(|first| first == '_' || first.is_ascii_alphabetic())\n        && characters.all(|character| character == '_' || character.is_ascii_alphanumeric())\n}\n\nfn env_state(declaration: &SecretDeclaration) -> SecretState {","sourceCodeStart":290,"sourceCodeEnd":326,"githubUrl":"https://github.com/jdx/mise/blob/9dcfcaa0dc8747a2577d3270b69bb9d8313b2807/src/system/secrets.rs#L290-L326","documentation":"The environment variable a secret maps to (the string form of the declaration or options.env) must satisfy valid_env_name: the first character is a letter or '_', and every following character is a letter, digit or '_'. Dashes, spaces and leading digits are rejected at config parse time, matching shell identifier rules.","triggerScenarios":"env values like \"CACHE-TOKEN\", \"7ZIP_HOME\" or \"CACHE TOKEN\" in a [bootstrap.secrets] declaration.","commonSituations":"Copying env var names that contain dashes from other ecosystems; machine-generated names; typos inserting spaces.","solutions":["Rename the variable to shell-identifier form: uppercase with underscores, e.g. CACHE_TOKEN","If a tool genuinely needs a dashed variable name, have a task or wrapper script export it from the underscore-named secret value"],"exampleFix":"# before\n[bootstrap.secrets]\ntoken = \"CACHE-TOKEN\"\n# after\n[bootstrap.secrets]\ntoken = \"CACHE_TOKEN\"","handlingStrategy":"validation","validationCode":"// Validate env var names before running bootstrap\nfn valid_env_name(name: &str) -> bool {\n    let mut chars = name.chars();\n    chars.next().is_some_and(|c| c == '_' || c.is_ascii_alphabetic())\n        && chars.all(|c| c == '_' || c.is_ascii_alphanumeric())\n}\nassert!(declarations.iter().all(|d| valid_env_name(&d.env)));","typeGuard":"fn is_valid_env_name(name: &str) -> bool {\n    let mut chars = name.chars();\n    chars.next().is_some_and(|c| c == '_' || c.is_ascii_alphabetic())\n        && chars.all(|c| c == '_' || c.is_ascii_alphanumeric())\n}","tryCatchPattern":null,"preventionTips":["Stick to UPPER_SNAKE_CASE for secret env var names","Remember dashes are invalid in both the secret name and its env var"],"tags":["bootstrap","secrets","environment-variables","validation"],"backgroundTag":"invalid-environment-variable-name","analyzedSha":"9dcfcaa0dc8747a2577d3270b69bb9d8313b2807","analyzedAt":"2026-08-17T14:28:50.624Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}