jdx/mise · error
uv project at has an empty project.name
Error message
uv project at {} has an empty project.name What it means
When discovering uv (Python) workspaces, mise reads pyproject.toml [project] tables and requires a non-empty project.name because the name becomes the workspace member's ProjectId. A [project] table with name = "" is invalid per uv/packaging rules, so mise refuses the project instead of producing a colliding or empty identifier.
Solutions
- Set a valid project name in pyproject.toml: name = "my-project".
- If the file is only a virtual/lock workspace config without a real project, remove the empty [project] table so it isn't treated as a project.
- Re-run your project scaffolder to fill in the name placeholder.
Example fix
# before [project] name = "" # after [project] name = "my-project"
Defensive patterns
Strategy: validation
Validate before calling
import TOML from '@iarna/toml';
const doc = TOML.parse(readFileSync('pyproject.toml', 'utf8'));
if (doc.project && (!doc.project.name || doc.project.name === '')) {
throw new Error('pyproject.toml [project] has empty name');
} Prevention
- Never scaffold with name = ""; fill placeholders immediately.
- Remove the [project] table from files that are not real Python projects.
When it happens
Trigger: discover_with_context reads a pyproject.toml where [project] exists but project.name is an empty string.
Common situations: Scaffolded pyproject.toml with a placeholder empty name; a template that failed to substitute the project name; someone deleted the name value while editing.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- uv workspace member at
- uv workspace member pattern
- exposes no executable scripts
- invalid Python entry point name
- has a wheel without a SHA256 hash
AI-assisted analysis of jdx/mise@533346cc37 (2026-09-17).
Data as JSON: /api/errors/b94d06f8a60484ba.
Report an issue: GitHub.
Appendix: source
Thrown at src/task/workspace/uv.rs:125
let mut known_roots = workspace_roots.clone();
let mut queue = workspace_roots.iter().cloned().collect::<VecDeque<_>>();
let mut manifests = BTreeMap::new();
while let Some(project_root) = queue.pop_front() {
if manifests.contains_key(&project_root) {
continue;
}
let relative = relative_root(&canonical_root, &project_root)?;
let pyproject_path = project_root.join(PYPROJECT_TOML);
let pyproject = if project_root == canonical_root {
root_pyproject.clone()
} else {
read_pyproject(context, &pyproject_path)?
};
let project = pyproject.project.as_ref().ok_or_else(|| {
eyre::eyre!("uv project at {} is missing [project]", relative.display())
})?;
if project.name.is_empty() {
bail!(
"uv project at {} has an empty project.name",
relative.display()
);
}
let id = ProjectId::new(self.id(), &normalize_package_name(&project.name))?;
let workspace_member = workspace_roots.contains(&project_root);
for dependency in dependency_names(&pyproject) {
let Some((source, source_base)) = effective_source(
&pyproject,
&root_pyproject,
&dependency,
workspace_member,
&project_root,
&canonical_root,
) else {
continue;
};View on GitHub (pinned to 533346cc37)