{"record":{"id":"fe1887c096be890c","repo":"lima-vm/lima","slug":"local-files-are-not-cached","errorCode":null,"errorMessage":"local files are not cached","messagePattern":"local files are not cached","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/downloader/downloader.go","lineNumber":553,"sourceCode":"\treturn algo.FromReader(f)\n}\n\n// Cached checks if the remote resource is in the cache.\n//\n// Download caches the remote resource if WithCache or WithCacheDir option is specified.\n// Local files are not cached.\n//\n// When the cache path already exists, Cached returns Result with StatusUsedCache.\nfunc Cached(remote string, opts ...Opt) (*Result, error) {\n\tvar o options\n\tif err := o.apply(opts); err != nil {\n\t\treturn nil, err\n\t}\n\tif o.cacheDir == \"\" {\n\t\treturn nil, errors.New(\"caching-only mode requires the cache directory to be specified\")\n\t}\n\tif IsLocal(remote) {\n\t\treturn nil, errors.New(\"local files are not cached\")\n\t}\n\n\tshad := cacheDirectoryPath(o.cacheDir, remote)\n\tshadData := filepath.Join(shad, \"data\")\n\tshadTime := filepath.Join(shad, \"time\")\n\tshadType := filepath.Join(shad, \"type\")\n\tshadDigest, err := cacheDigestPath(shad, o.expectedDigest)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// Checking if data file exists is safe without locking.\n\tif _, err := os.Stat(shadData); err != nil {\n\t\treturn nil, err\n\t}\n\n\t// But validating the digest or the data file must take the lock to avoid races\n\t// with parallel downloads.","sourceCodeStart":535,"sourceCodeEnd":571,"githubUrl":"https://github.com/lima-vm/lima/blob/dd909d0973cd84fa35f9e1693181b4585ea616c1/pkg/downloader/downloader.go#L535-L571","documentation":"The cache is keyed by the remote URL (by-url-sha256). Local files (paths without a scheme, or file:// URLs) have no remote identity to cache and are documented as not cached, so Cached() rejects them immediately with this error.","triggerScenarios":"Calling downloader.Cached(\"/path/to/file.iso\"), Cached(\"~/image.qcow2\"), or Cached(\"file:///abs/path\") — any remote string where IsLocal() returns true.","commonSituations":"Configuration switched a template's image URL to a local file during testing and the code still goes through the caching path; users passing file:// URLs copied from docs assuming uniform behavior.","solutions":["Only call Cached for http(s)/remote URLs; guard with downloader.IsLocal(remote) first","For local files, use Download with the local path (local files are copied, not cached) or handle them directly","If testing, serve the file over a local HTTP server so it has a remote URL key"],"exampleFix":"// before\nres, err := downloader.Cached(isoPath, opts...)\n// after\nif downloader.IsLocal(isoPath) {\n    // handle local file directly, skip cache lookup\n} else {\n    res, err = downloader.Cached(isoPath, opts...)\n}","handlingStrategy":"validation","validationCode":"if downloader.IsLocal(remote) {\n    // bypass the cache entirely for local paths / file:// URLs\n    return handleLocalFile(remote)\n}","typeGuard":null,"tryCatchPattern":"res, err := downloader.Cached(remote, opts...)\nif err != nil && strings.Contains(err.Error(), \"local files are not cached\") {\n    return handleLocalFile(remote) // fallback path for file:// or bare paths\n}","preventionTips":["Check IsLocal(remote) before calling Cached","Keep image references in templates as http(s) URLs when caching is expected","Document that file:// and bare paths skip the cache","Serve local test files over HTTP if cache semantics are needed"],"tags":["go","api-misuse","cache","validation"],"backgroundTag":"unsupported-input-type","analyzedSha":"dd909d0973cd84fa35f9e1693181b4585ea616c1","analyzedAt":"2026-09-01T14:24:59.842Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}