{"record":{"id":"59b15a7461a54cc2","repo":"jdx/mise","slug":"cargo-workspace-member-pattern-member-must-be","errorCode":null,"errorMessage":"Cargo workspace member pattern {member:?} must be relative","messagePattern":"Cargo workspace member pattern (.+?) must be relative","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/task/workspace/cargo.rs","lineNumber":254,"sourceCode":"fn discover_members(\n    pattern_root: &Path,\n    canonical_root: &Path,\n    members: &[String],\n    excludes: &[Pattern],\n    context: &WorkspaceDiscoveryContext,\n) -> Result<BTreeSet<PathBuf>> {\n    let options = MatchOptions {\n        case_sensitive: true,\n        require_literal_separator: true,\n        require_literal_leading_dot: true,\n    };\n    // Use the caller's non-canonical path for globbing. Windows canonical paths\n    // use a verbatim `\\\\?\\` prefix whose `?` is interpreted as a glob token.\n    let escaped_root = Pattern::escape(&pattern_root.to_string_lossy());\n    let mut roots = BTreeSet::new();\n    for member in members {\n        if Path::new(member).is_absolute() {\n            bail!(\"Cargo workspace member pattern {member:?} must be relative\");\n        }\n        let pattern = format!(\"{escaped_root}/{member}\");\n        for candidate in glob::glob_with(&pattern, options)\n            .wrap_err_with(|| format!(\"invalid Cargo workspace member pattern {member:?}\"))?\n        {\n            let candidate = candidate.wrap_err_with(|| {\n                format!(\"failed to evaluate Cargo workspace member pattern {member:?}\")\n            })?;\n            if !context.is_file(&candidate.join(CARGO_TOML)) {\n                continue;\n            }\n            let candidate = context.canonicalize(&candidate).wrap_err_with(|| {\n                format!(\n                    \"failed to resolve Cargo workspace member {}\",\n                    candidate.display()\n                )\n            })?;\n            let relative = relative_root(canonical_root, &candidate)?;","sourceCodeStart":236,"sourceCodeEnd":272,"githubUrl":"https://github.com/jdx/mise/blob/533346cc374382b41ec5ff70536252b2e96e725c/src/task/workspace/cargo.rs#L236-L272","documentation":"mise's Cargo workspace task provider globs workspace member patterns from Cargo.toml to discover member crates. Member patterns are joined onto the workspace root as `<root>/<member>` and globbed, so they must be relative paths or globs. When a member entry is an absolute path (e.g. `/foo` or `C:\\foo`), the provider bails with this error because an absolute member would produce a broken or unintended glob pattern.","triggerScenarios":"Running a task that triggers workspace discovery when a `Cargo.toml` `[workspace] members = [...]` (or `default-members`) entry is an absolute path like `members = [\"/opt/crates/util\"]` instead of a relative path or glob.","commonSituations":"Hand-edited Cargo.toml where someone pasted an absolute path; tools or scripts generating members entries from absolute paths; cross-platform configs where Windows drive-letter paths sneak in.","solutions":["Change the members entry in Cargo.toml to a path relative to the workspace root (e.g. `\"crates/util\"` or `\"crates/*\"`).","If the member genuinely lives outside the workspace root, move it under the root or restructure; Cargo itself also forbids absolute member patterns relative resolution outside the root.","Verify with `cargo metadata` that Cargo accepts the workspace before running mise tasks."],"exampleFix":"# before (Cargo.toml)\n[workspace]\nmembers = [\"/home/user/proj/crates/util\"]\n\n# after\n[workspace]\nmembers = [\"crates/util\"]","handlingStrategy":"validation","validationCode":"fn validate_members(members: &[String]) -> Result<(), String> {\n    for m in members {\n        if Path::new(m).is_absolute() {\n            return Err(format!(\"member {m:?} must be relative to workspace root\"));\n        }\n    }\n    Ok(())\n}","typeGuard":"fn is_relative_member(m: &str) -> bool { !Path::new(m).is_absolute() }","tryCatchPattern":null,"preventionTips":["Always write members as paths relative to the workspace root in Cargo.toml","Let `cargo new` / generators place members under the root and use globs like \"crates/*\"","CI-lint Cargo.toml to reject absolute member entries"],"tags":["cargo","workspace","config","glob"],"backgroundTag":"invalid-argument-value","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"}