lima-vm/lima · error
template %#q not found
Error message
template %#q not found
What it means
templatestore.Read searches every directory in the template search path (LIMA_TEMPLATES_PATH, or ~/.lima/templates plus share/lima/templates) for a file matching the template name, appending ".yaml" when the name has no usable extension. This error is returned only after the name passed the ".." security check and no file was found in any search directory. It is the library's way of saying the requested template does not exist under any configured template directory.
Source
Thrown at pkg/templatestore/templatestore.go:72
}
paths, err := templatesPaths()
if err != nil {
return nil, err
}
ext := filepath.Ext(name)
// Append .yaml extension if name doesn't have an extension, or if it starts with a digit.
// So "docker.sh" would remain unchanged but "ubuntu-24.04" becomes "ubuntu-24.04.yaml".
if len(ext) < 2 || unicode.IsDigit(rune(ext[1])) {
name += ".yaml"
}
for _, templatesDir := range paths {
// Normalize filePath for error messages because template names always use forward slashes
filePath := filepath.Clean(filepath.Join(templatesDir, name))
if b, err := os.ReadFile(filePath); !errors.Is(err, os.ErrNotExist) {
return b, err
}
}
return nil, fmt.Errorf("template %#q not found", name)
}
const Default = "default"
// Templates returns a list of Template structures containing the Name and Location for each template.
// It searches all template directories, but only the first template of a given name is recorded.
// Only non-hidden files with a ".yaml" file extension are considered templates.
// The final result is sorted alphabetically by template name.
func Templates() ([]Template, error) {
paths, err := templatesPaths()
if err != nil {
return nil, err
}
templates := make(map[string]string)
for _, templatesDir := range paths {
if _, err := os.Stat(templatesDir); os.IsNotExist(err) {
continueView on GitHub (pinned to dd909d0973)
Solutions
- Check the template name spelling and run `limactl template ls` (or list ~/.lima/templates and $(dirname $(which limactl))/../share/lima/templates) to see available names.
- If using a custom LIMA_TEMPLATES_PATH, verify it includes the directory containing the template file, with entries separated by the OS path list separator.
- Reinstall/repair Lima so the stock templates exist under share/lima/templates (e.g. `brew reinstall lima`).
- Remember the .yaml auto-append: if your file is `foo.txt`, reference it as `foo.txt` (extension >=2 chars and non-digit second char keeps the name unchanged); otherwise create it as `foo.yaml`.
- Copy or symlink your custom template into one of the searched template directories, ensuring the resolved path contains no ".." (which is rejected earlier with a different error).
Example fix
// before
b, err := templatestore.Read("ubuntu-lts") // typo, no such template
// after
b, err := templatestore.Read("ubuntu-24.04") // resolves to ubuntu-24.04.yaml Defensive patterns
Strategy: validation
Validate before calling
names, err := templatestore.Templates()
if err != nil { return err }
var found bool
for _, t := range names {
if t.Name == requested || t.Name == requested+".yaml" { found = true; break }
}
if !found { return fmt.Errorf("template %q not available; pick one of: %v", requested, names) }
_, err = templatestore.Read(requested) Try / catch
b, err := templatestore.Read(name)
if err != nil {
if strings.Contains(err.Error(), "not found") {
// fall back to default template
return templatestore.Read(templatestore.Default)
}
return err
} Prevention
- Validate user-supplied template names against templatestore.Templates() before calling Read.
- Avoid depending on LIMA_TEMPLATES_PATH overrides in scripts without checking the dir contents first.
- Remember Read appends .yaml to extension-less names; name files accordingly.
- After package upgrades, verify stock templates exist with `limactl template ls`.
When it happens
Trigger: Calling templatestore.Read(name) (directly or via loadOrCreateInstance / New) when no file named <name>.yaml (or the given extension) exists in any of the directories returned by templatesPaths(). Also triggered by typos in the template name, referencing a template that was never installed (e.g. missing Homebrew share/lima/templates files), or a LIMA_TEMPLATES_PATH that omits the directory holding the template.
Common situations: Running `limactl start <name>` with a misspelled or non-existent template; upgrading Lima via a package manager that failed to install the stock templates; pointing LIMA_TEMPLATES_PATH at a custom dir that lacks the requested file; passing a name with a numeric version suffix and expecting a non-.yaml extension to resolve (Read appends .yaml, e.g. "ubuntu-24.04" -> "ubuntu-24.04.yaml").
Related errors
- unsupported shell %#q for Windows guest, must be one of %v
- instance %q not found
- disk format %#q not supported, use `qcow2` or `raw` instead
- failed to check if the autostart entry for instance %#q is r
- the YAML is invalid, attempted to save the buffer as %#q but
AI-assisted analysis of lima-vm/lima@dd909d0973 (2026-09-01).
Data as JSON: /api/errors/02fc1ef908dfb8c1.
Report an issue: GitHub.