Validate VM names, including Windows reserved device names
@NovusEdge is already working on this.
Since Sep 7, 2026.
- Dominant language
- Go
- Stars
- 2
- Forks
- 0
- Avg merge
- 3h 51m
- Merged PRs (30d)
- 80
Description
Problem
Stoat does not validate a VM name anywhere. A name goes from stoat create straight into a directory name under the data root, and filepath.Base(v.Dir) reads it back throughout internal/core.
On Windows, CON, PRN, AUX, NUL, COM1-COM9 and LPT1-LPT9 are reserved device names at every path level, with or without an extension. A VM named nul maps to a device instead of failing as a normal error.
The gap is wider than Windows. Nothing today rejects a name containing a path separator, a leading dash, a name that is . or .., or an empty name.
Found by
Surveying #83's "Handle Windows paths, drive letters, reserved names, long paths, symlinks/reparse points" line, during the work in #113. #113 fixed the drive-letter half of that line and left this one.
Proposal
One validation function, called from stoat create and stoat init, that rejects:
- A Windows reserved device name, case-insensitive, with or without an extension.
- A name containing a path separator, or
., or... - An empty name, or one that is only whitespace.
- A leading dash, which reads as a flag in most argv positions.
The rule should apply on every platform, not only Windows. A data root is portable, and a VM created on Linux should not become unusable when the same directory is opened on Windows.
Acceptance criteria
- One function owns the rule.
createandinitboth call it. - The error names the rejected character or word and what a valid name looks like.
--jsonand MCP report it with an existing error code;invalid_speclooks right.- A table test covers each rejected class and a set of valid names, and runs on every platform.
- Documentation states the rule where VM naming is described.
Size
Roughly 30-50 lines plus tests. The open decision is where in the create pipeline to enforce it and whether an existing VM with a now-invalid name keeps working, which it should.
Out of scope
Paths beyond 260 characters, and symlink/reparse-point handling. Both need testing on real Windows before anyone can size them, and both are tracked under #83.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.