{"record":{"id":"02fc1ef908dfb8c1","repo":"lima-vm/lima","slug":"template-q-not-found","errorCode":null,"errorMessage":"template %#q not found","messagePattern":"template %#q not found","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/templatestore/templatestore.go","lineNumber":72,"sourceCode":"\t}\n\tpaths, err := templatesPaths()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\text := filepath.Ext(name)\n\t// Append .yaml extension if name doesn't have an extension, or if it starts with a digit.\n\t// So \"docker.sh\" would remain unchanged but \"ubuntu-24.04\" becomes \"ubuntu-24.04.yaml\".\n\tif len(ext) < 2 || unicode.IsDigit(rune(ext[1])) {\n\t\tname += \".yaml\"\n\t}\n\tfor _, templatesDir := range paths {\n\t\t// Normalize filePath for error messages because template names always use forward slashes\n\t\tfilePath := filepath.Clean(filepath.Join(templatesDir, name))\n\t\tif b, err := os.ReadFile(filePath); !errors.Is(err, os.ErrNotExist) {\n\t\t\treturn b, err\n\t\t}\n\t}\n\treturn nil, fmt.Errorf(\"template %#q not found\", name)\n}\n\nconst Default = \"default\"\n\n// Templates returns a list of Template structures containing the Name and Location for each template.\n// It searches all template directories, but only the first template of a given name is recorded.\n// Only non-hidden files with a \".yaml\" file extension are considered templates.\n// The final result is sorted alphabetically by template name.\nfunc Templates() ([]Template, error) {\n\tpaths, err := templatesPaths()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\ttemplates := make(map[string]string)\n\tfor _, templatesDir := range paths {\n\t\tif _, err := os.Stat(templatesDir); os.IsNotExist(err) {\n\t\t\tcontinue","sourceCodeStart":54,"sourceCodeEnd":90,"githubUrl":"https://github.com/lima-vm/lima/blob/dd909d0973cd84fa35f9e1693181b4585ea616c1/pkg/templatestore/templatestore.go#L54-L90","documentation":"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.","triggerScenarios":"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.","commonSituations":"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\").","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)."],"exampleFix":"// before\nb, err := templatestore.Read(\"ubuntu-lts\") // typo, no such template\n// after\nb, err := templatestore.Read(\"ubuntu-24.04\") // resolves to ubuntu-24.04.yaml","handlingStrategy":"validation","validationCode":"names, err := templatestore.Templates()\nif err != nil { return err }\nvar found bool\nfor _, t := range names {\n    if t.Name == requested || t.Name == requested+\".yaml\" { found = true; break }\n}\nif !found { return fmt.Errorf(\"template %q not available; pick one of: %v\", requested, names) }\n_, err = templatestore.Read(requested)","typeGuard":null,"tryCatchPattern":"b, err := templatestore.Read(name)\nif err != nil {\n    if strings.Contains(err.Error(), \"not found\") {\n        // fall back to default template\n        return templatestore.Read(templatestore.Default)\n    }\n    return err\n}","preventionTips":["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`."],"tags":["templates","file-not-found","configuration","cli"],"backgroundTag":"template-not-found","analyzedSha":"dd909d0973cd84fa35f9e1693181b4585ea616c1","analyzedAt":"2026-09-01T14:24:59.842Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}