{"record":{"id":"3ce6e542c01ba3b7","repo":"jdx/mise","slug":"brew-cask-generate-completions-from-executable-re-3ce6e5","errorCode":null,"errorMessage":"brew-cask: generate_completions_from_executable requires an executable","messagePattern":"brew-cask: generate_completions_from_executable requires an executable","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/system/packages/brew/cask/artifacts.rs","lineNumber":414,"sourceCode":"        source,\n        target: target.or_else(|| declared_target(value)),\n    }))\n}\n\npub(super) fn parse_generated_completion_artifact(\n    value: &Value,\n) -> Result<Option<GeneratedCompletionArtifact>> {\n    let Some(generated) = value\n        .as_object()\n        .and_then(|o| o.get(\"generate_completions_from_executable\"))\n    else {\n        return Ok(None);\n    };\n    let Value::Array(values) = generated else {\n        return Ok(None);\n    };\n    if values.is_empty() {\n        bail!(\"brew-cask: generate_completions_from_executable requires an executable\");\n    }\n    let options = values.last().and_then(Value::as_object);\n    if let Some(options) = options {\n        reject_unsupported_artifact_fields(\n            \"generate_completions_from_executable\",\n            options,\n            &[\"base_name\", \"shell_parameter_format\", \"shells\"],\n        )?;\n    }\n    let command_values = if options.is_some() {\n        &values[..values.len() - 1]\n    } else {\n        values.as_slice()\n    };\n    let executable = command_values\n        .first()\n        .and_then(Value::as_str)\n        .ok_or_else(|| {","sourceCodeStart":396,"sourceCodeEnd":432,"githubUrl":"https://github.com/jdx/mise/blob/533346cc374382b41ec5ff70536252b2e96e725c/src/system/packages/brew/cask/artifacts.rs#L396-L432","documentation":"`generate_completions_from_executable` artifacts must name an executable to run in order to generate shell completions. When the artifact's value parses as an array but is empty (or resolves to an empty executable list), parsing fails because there is no way to produce completions. This is a fail-fast validation so misconfigured casks error at parse time instead of at install time.","triggerScenarios":"A cask defines a `generate_completions_from_executable` artifact whose array value is empty (`generate_completions_from_executable = []`), encountered in `parse_generated_completion_artifact` after the `values.is_empty()` check.","commonSituations":"Hand-editing a cask's artifacts and deleting the executable entry but leaving the empty table/array, or a templated/generated cask where the executable list evaluated to nothing.","solutions":["Add the executable name to the `generate_completions_from_executable` array in the cask definition.","If completions are not needed, remove the `generate_completions_from_executable` artifact stanza entirely."],"exampleFix":"// before\ngenerate_completions_from_executable = []\n// after\ngenerate_completions_from_executable = [\"mytool\"]","handlingStrategy":"validation","validationCode":"const arr = cask.generate_completions_from_executable;\nif (Array.isArray(arr) && arr.length === 0)\n  throw new Error(\"generate_completions_from_executable requires an executable\");","typeGuard":"function hasExecutable(v) {\n  return Array.isArray(v) && v.length > 0 && typeof v[0] === \"string\";\n}","tryCatchPattern":"try {\n  parseCaskArtifacts(cask);\n} catch (err) {\n  if (err.message.includes(\"requires an executable\")) {\n    // supply an executable or drop the artifact\n  } else throw err;\n}","preventionTips":["Never leave a generate_completions_from_executable array empty; delete the stanza instead.","Lint cask files for empty arrays in completion artifacts."],"tags":["brew-cask","config","completions","empty-value"],"backgroundTag":"empty-required-field","analyzedSha":"533346cc374382b41ec5ff70536252b2e96e725c","analyzedAt":"2026-09-17T13:35:38.149Z","contentChangedAt":"2026-09-17T13:35:38.149Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}