{"record":{"id":"24df1e794c934887","repo":"nektos/act","slug":"find-cache-w","errorCode":null,"errorMessage":"find cache: %w","messagePattern":"find cache: %w","errorType":"http","errorClass":null,"httpStatus":500,"severity":"error","filePath":"pkg/artifactcache/handler.go","lineNumber":382,"sourceCode":"\treturn func(w http.ResponseWriter, r *http.Request, params httprouter.Params) {\n\t\th.logger.Debugf(\"%s %s\", r.Method, r.RequestURI)\n\t\thandler(w, r, params)\n\t\tgo h.gcCache()\n\t}\n}\n\n// if not found, return (nil, nil) instead of an error.\nfunc findCache(db *bolthold.Store, keys []string, version string) (*Cache, error) {\n\tcache := &Cache{}\n\tfor _, prefix := range keys {\n\t\t// if a key in the list matches exactly, don't return partial matches\n\t\tif err := db.FindOne(cache,\n\t\t\tbolthold.Where(\"Key\").Eq(prefix).\n\t\t\t\tAnd(\"Version\").Eq(version).\n\t\t\t\tAnd(\"Complete\").Eq(true).\n\t\t\t\tSortBy(\"CreatedAt\").Reverse()); err == nil || !errors.Is(err, bolthold.ErrNotFound) {\n\t\t\tif err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"find cache: %w\", err)\n\t\t\t}\n\t\t\treturn cache, nil\n\t\t}\n\t\tprefixPattern := fmt.Sprintf(\"^%s\", regexp.QuoteMeta(prefix))\n\t\tre, err := regexp.Compile(prefixPattern)\n\t\tif err != nil {\n\t\t\tcontinue\n\t\t}\n\t\tif err := db.FindOne(cache,\n\t\t\tbolthold.Where(\"Key\").RegExp(re).\n\t\t\t\tAnd(\"Version\").Eq(version).\n\t\t\t\tAnd(\"Complete\").Eq(true).\n\t\t\t\tSortBy(\"CreatedAt\").Reverse()); err != nil {\n\t\t\tif errors.Is(err, bolthold.ErrNotFound) {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\treturn nil, fmt.Errorf(\"find cache: %w\", err)\n\t\t}","sourceCodeStart":364,"sourceCodeEnd":400,"githubUrl":"https://github.com/nektos/act/blob/4f411281417e88660bea1c1a1749aa71ae0bd60f/pkg/artifactcache/handler.go#L364-L400","documentation":"findCache queries the embedded bolthold/bolt database for a cache entry matching a key (exact match first). This error means the exact-match query failed with a real database error (not bolthold.ErrNotFound, which is handled by falling through to the prefix-regex lookup). Typical causes are a corrupted .db file, a bolt database locked by another process, or an unusable index inside the cache DB.","triggerScenarios":"Calling the artifact cache handler's lookup path (handler.go:193, i.e. any actions/cache 'restore' request hitting the local cache server) while the bolthold store under ~/.cache/act/.cache.db is locked by a concurrent act run, was killed mid-write, or has a stale/corrupt index for the Key/Version/Complete query.","commonSituations":"Two act instances sharing the same host cache dir; a previous act process was SIGKILLed during cache write leaving a torn bolt transaction; the cache directory is on a filesystem that does not support bolt's flock (NFS/network mounts); disk full during a prior insert.","solutions":["Stop other act runs using the same cache dir, then delete ~/.cache/act (or the configured ACT_CACHE_SERVER_DIR) so a fresh DB is created","Verify no stale act process still holds the bolt file lock (lsof ~/.cache/act/*.db)","Move the cache dir off NFS/network storage to a local filesystem","If it recurs, capture the wrapped bolthold error text — 'database is locked' vs 'invalid database' points to concurrency vs corruption"],"exampleFix":null,"handlingStrategy":"fallback","validationCode":"// Before starting parallel runs, ensure cache dir ownership\nif fi, err := os.Stat(cacheDir); err == nil && fi.IsDir() {\n    // check no other act holds the db lock\n    if out, _ := exec.Command(\"lsof\", filepath.Join(cacheDir, \"actcache.db\")).Output(); len(out) > 0 {\n        log.Warn(\"cache db already open by another process\")\n    }\n}","typeGuard":null,"tryCatchPattern":"err := dbFind(...)\nif err != nil {\n    if errors.Is(err, bolthold.ErrNotFound) { /* miss, rebuild */ }\n    else { log.Warnf(\"cache lookup failed, treating as miss: %v\", err); /* serve without cache */ }\n}","preventionTips":["Give each concurrent act run its own cache directory","Keep the cache dir on a local filesystem, never NFS","Treat cache as disposable: delete the dir on any corruption and let it rebuild"],"tags":["artifact-cache","bolthold","database","act"],"backgroundTag":null,"analyzedSha":"4f411281417e88660bea1c1a1749aa71ae0bd60f","analyzedAt":"2026-08-15T09:19:46.307Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}