{"record":{"id":"5752ab318ee0d677","repo":"Leantime/leantime","slug":"plugin-s-is-not-installed-5752ab","errorCode":null,"errorMessage":"Plugin %s is not installed","messagePattern":"Plugin (.+?) is not installed","errorType":"console","errorClass":"RuntimeException","httpStatus":null,"severity":"warning","filePath":"app/Command/EnablePluginCommand.php","lineNumber":38,"sourceCode":"{\n    /**\n     * {@inheritdoc}\n     */\n    protected function configure(): void\n    {\n        $this->addArgument('plugin', InputArgument::REQUIRED, 'The plugin name');\n    }\n\n    /**\n     * {@inheritdoc}\n     */\n    protected function executeCommand(): int\n    {\n        $name = $this->input->getArgument('plugin');\n        $plugin = $this->getPlugin($name);\n\n        if (! isset($plugin->id)) {\n            throw new RuntimeException(sprintf('Plugin %s is not installed', $plugin->name));\n        }\n\n        if ($plugin->enabled) {\n            throw new RuntimeException(sprintf('Plugin %s is already enabled', $plugin->name));\n        }\n\n        if (! $this->confirm(sprintf('Enable plugin %s', $plugin->name))) {\n            return Command::SUCCESS;\n        }\n\n        return $this->plugins->enablePlugin($plugin->id) ? Command::SUCCESS : Command::FAILURE;\n    }\n}\n","sourceCodeStart":20,"sourceCodeEnd":52,"githubUrl":"https://github.com/Leantime/leantime/blob/9a9f49f1008f4782b30f6723c54228f4f992e636/app/Command/EnablePluginCommand.php#L20-L52","documentation":"This warning comes from the artisan command that clears the language cache (app/Command/ClearLanguage.php:60). For every language in the list it calls `Cache::store('installation')->forget('languages.lang_' . $key)`; Laravel's forget() returns false when the key does not exist in that store, and the command prints 'Failed to clear: <key>'. It does not mean the command broke — it means the cache entry was already absent, lives under a different cache driver/prefix than the 'installation' store currently configured, or was never written by this installation.","triggerScenarios":"Running the language-clear command when: (1) the language cache entries were already evicted or expired (file/redis cache TTL, manual cache:clear earlier); (2) the cache configuration changed between when the entries were written and now (e.g. switched CACHE_DRIVER from file to redis or the database driver), so forget() looks in an empty store; (3) a CACHE_PREFIX or separate 'installation' store database differs between web requests (which wrote the entries) and the CLI process (different .env, or CLI running as a different user reading another cache path); (4) the language was added after the last cache write, so its key never existed.","commonSituations":"Dockerized Leantime where the web container uses redis but an exec'd CLI container defaults to the file driver; cache stored on a shared NFS/storage volume with per-user permissions so artisan runs as root and reads a different cache directory; running the command right after `make clear-cache`; multi-instance deployments where instance A holds the warm cache and the command runs on instance B.","solutions":["First re-run the command — if the second run warns for the same keys immediately, the CLI and the web runtime are almost certainly using different cache stores; compare `php bin/leantime config:cache`-resolved values vs what the web container uses.","Verify the 'installation' store configuration in app/Core/Configuration/laravelConfig.php (Leantime keeps ALL Laravel config there, not config/*.php) and ensure CACHE_DRIVER/CACHE_PREFIX .env values are identical for web and CLI.","If the keys were simply never written or already expired, ignore the warning: a cache miss is the desired end state — the language list will be rebuilt on next request.","Flush the whole installation store if you need certainty: `php bin/leantime cache:clear` (accepting a broader cache loss), then re-run the language command and expect all keys to 'fail' benignly.","If using redis/database cache in Docker, confirm all containers point at the same redis host and DB index before rerunning."],"exampleFix":"// before — forget() false is reported as a failure even when the entry is simply absent\n$result = Cache::store('installation')->forget('languages.lang_' . $key);\nif ($result) {\n    $this->components->info('Cleared: ' . $key);\n} else {\n    $this->components->warn('Failed to clear: ' . $key);\n}\n\n// after — distinguish 'already absent' from an actual store error\ntry {\n    $existed = Cache::store('installation')->forget('languages.lang_' . $key);\n    $this->components->info($existed ? \"Cleared: {$key}\" : \"Not cached (already clear): {$key}\");\n} catch (\\Throwable $e) {\n    \\Illuminate\\Support\\Facades\\Log::error($e);\n    $this->components->warn(\"Failed to clear: {$key} — \" . $e->getMessage());\n}","handlingStrategy":"validation","validationCode":"// Before running the language cache clear, validate the CLI sees the same cache store the web runtime writes to\n$driver = config('cache.stores.installation.driver'); // must match what served requests used\n$probeKey = 'languages.lang_' . app()->make(\\Leantime\\Domain\\Setting\\Services\\Setting::class)?->getSetting('companysettings.language') ?? 'en-US';\n$hasEntries = \\Illuminate\\Support\\Facades\\Cache::store('installation')->get($probeKey) !== null;\nif (! $hasEntries) {\n    // cache is already cold or CLI/web stores diverge — expect benign 'Failed to clear' warnings\n}","typeGuard":null,"tryCatchPattern":"// If you wrap the clear in application code, distinguish 'absent' (fine) from store errors (log)\ntry {\n    $existed = Cache::store('installation')->forget('languages.lang_' . $key);\n    logger()->debug($existed ? \"cleared {$key}\" : \"already absent {$key}\");\n} catch (\\Psr\\SimpleCache\\InvalidArgumentException | \\RedisException $e) {\n    \\Illuminate\\Support\\Facades\\Log::error($e);\n    // surface store misconfiguration; do not retry blindly against a wrong store\n}","preventionTips":["Pin identical CACHE_DRIVER / CACHE_PREFIX / redis host+DB in .env for web and CLI containers before running cache commands.","Remember forget()===false is a cache miss, not an error — do not alert on it.","After switching cache drivers, flush the old store once (or accept benign misses on the new one).","Run `php bin/leantime about` (or dump config) inside the same container/context the command runs in to verify the resolved driver."],"tags":["cache","console-command","i18n","cache-driver-mismatch","laravel"],"backgroundTag":"cache-forget-key-miss","analyzedSha":"9a9f49f1008f4782b30f6723c54228f4f992e636","analyzedAt":"2026-08-21T02:37:38.966Z","schemaVersion":2},"datasetVersion":"2026-08-21T03:17:12.404Z"}