jdx/mise · error · eyre::Report
workspace {kind} ID {value:?} contains surrounding whitespac
Error message
workspace {kind} ID {value:?} contains surrounding whitespace or control characters What it means
validate_id_part rejects a provider or local project id whose trimmed form differs from itself (leading/trailing whitespace) or that contains any Unicode control character anywhere. It runs for both halves of a ProjectId during construction and parsing, so ids must be clean, single-line tokens.
Source
Thrown at src/task/workspace.rs:68
}
impl FromStr for ProjectId {
type Err = eyre::Report;
fn from_str(value: &str) -> Result<Self> {
let Some((provider, local_id)) = value.split_once(':') else {
bail!("workspace project ID {value:?} must include a provider namespace");
};
Self::new(provider, local_id)
}
}
fn validate_id_part(kind: &str, value: &str) -> Result<()> {
if value.is_empty() {
bail!("workspace {kind} ID cannot be empty");
}
if value.trim() != value || value.chars().any(char::is_control) {
bail!(
"workspace {kind} ID {value:?} contains surrounding whitespace or control characters"
);
}
if kind == "provider" && value.contains(':') {
bail!("workspace provider ID {value:?} cannot contain ':'");
}
Ok(())
}
/// A project discovered from ecosystem-specific workspace metadata.
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub(crate) struct WorkspaceProject {
/// Stable identity used by dependency edges and task scoping.
pub id: ProjectId,
/// Normalized path relative to the workspace root. `.` represents the root.
pub root: PathBuf,
/// Provider-neutral facts that consumers may use for inspection or inference.
pub metadata: BTreeMap<String, String>,View on GitHub (pinned to 6f52dcdf99)
Solutions
- Strip surrounding whitespace from the offending dependency string or override key in mise.toml
- Re-type the id instead of pasting, or paste with whitespace-trimming enabled
- If the id is provider-derived, fix the source metadata (the go.mod module path or Cargo package name contains the bad character)
- Add a config lint in CI that rejects whitespace/control characters in project ids
Example fix
# before (mise.toml) [monorepo.projects."node:app"] depends_add = [" node:lib "] # after [monorepo.projects."node:app"] depends_add = ["node:lib"]
Defensive patterns
Strategy: validation
Validate before calling
fn is_clean_id_part(value: &str) -> bool {
!value.is_empty()
&& value.trim() == value
&& !value.chars().any(char::is_control)
}
fn is_valid_project_id(value: &str) -> bool {
value.split_once(':')
.map(|(p, l)| is_clean_id_part(p) && is_clean_id_part(l))
.unwrap_or(false)
} Type guard
fn is_valid_project_id(value: &str) -> bool {
match value.split_once(':') {
Some((provider, local)) => {
[provider, local].iter().all(|part| {
!part.is_empty() && part.trim() == *part && !part.chars().any(char::is_control)
})
}
None => false,
}
} Try / catch
// treat as config data error: report the exact id and its byte-level content
Err(report) if report.to_string().contains("whitespace or control") => {
eprintln!("project id {id:?} needs trimming; got bytes {:?}", id.as_bytes());
continue;
} Prevention
- Trim copied ids before pasting into mise.toml lists
- Avoid multiline TOML strings for ids; keep each id on one line
- Enable editor trim-trailing-whitespace on save for config files
When it happens
Trigger: A [monorepo.projects] dependency entry like " node:app" or "node:app\t" in mise.toml (TOML basic strings keep inner whitespace); a value copied with an embedded newline from a multiline string; a provider building an id from a go module path that itself contains a control character after unescaping.
Common situations: Copy-pasting ids with a stray leading/trailing space; editors adding trailing whitespace; diff/merge tools introducing a carriage return into a quoted string.
Understand the failure class
Background: "invalid id" errors: invalid identifier format — why libraries reject IDs before lookup, and how to fix them — this error's family across 37 libraries.
Related errors
- workspace {kind} ID cannot be empty
- workspace project {:?} depends on unknown project {:?}
- removed workspace project {id:?} cannot define other overrid
- workspace project {id:?} has absolute root {root:?}; roots m
- workspace project {id:?} has root {root:?} that escapes the
AI-assisted analysis of jdx/mise@6f52dcdf99 (2026-08-22).
Data as JSON: /api/errors/0f3bbb833b1ea3a4.
Report an issue: GitHub.