{"record":{"id":"4446fac17306fbd1","repo":"ArchiveBox/ArchiveBox","slug":"plugin-not-found-key","errorCode":null,"errorMessage":"Plugin not found: {key}","messagePattern":"Plugin not found: (.+?)","errorType":"http","errorClass":"Http404","httpStatus":404,"severity":"warning","filePath":"archivebox/plugins/views.py","lineNumber":379,"sourceCode":"        rows[\"Name\"].append(\"(no plugins found)\")\n        rows[\"Source\"].append(\"-\")\n        rows[\"Path\"].append(mark_safe(\"<code>abx_plugins/plugins/</code> or <code>data/custom_plugins/</code>\"))\n        rows[\"Hooks\"].append(\"-\")\n        rows[\"Config\"].append(\"-\")\n\n    return TableContext(\n        title=\"Installed plugins\",\n        table=rows,\n    )\n\n\n@render_with_item_view\ndef plugin_detail_view(request: HttpRequest, key: str, **kwargs) -> ItemContext:\n    assert is_superuser(request), \"Must be a superuser to view configuration settings.\"\n\n    plugin = get_filesystem_plugins().get(key)\n    if plugin is None:\n        raise Http404(f\"Plugin not found: {key}\")\n\n    plugin_name = str(plugin[\"name\"])\n    config = plugin.get(\"config\") or {}\n    properties = config.get(\"properties\") or {}\n    machine_admin_url = get_machine_admin_url()\n    docs_url = get_plugin_docs_url(plugin_name)\n\n    summary_section: SectionData = {\n        \"name\": \"Summary\",\n        \"description\": mark_safe(\n            str(format_html('<code>{}</code><br/><a href=\"{}\">Plugin documentation</a>', plugin[\"path\"], docs_url)),\n        ),\n        \"fields\": {\n            \"id\": key,\n            \"name\": plugin_name,\n            \"source\": plugin[\"source\"],\n        },\n        \"help_texts\": {},","sourceCodeStart":361,"sourceCodeEnd":397,"githubUrl":"https://github.com/ArchiveBox/ArchiveBox/blob/74564b28220090664f919479e82cbf454125fa34/archivebox/plugins/views.py#L361-L397","documentation":"plugin_detail_view looks up a plugin by key from get_filesystem_plugins(); when the key is absent it raises Http404('Plugin not found: {key}'). Django converts this to a 404 page. The view requires superuser first, so only authenticated admins browsing plugin detail pages hit this.","triggerScenarios":"Visiting the plugin detail admin URL with a key that is not among currently discovered filesystem plugins — typos in key, plugin directory deleted/renamed, plugin failing discovery (invalid manifest) so it never registers.","commonSituations":"Bookmark to a plugin removed in an upgrade; plugin directory not present because extras/dependencies not installed; plugin discovery error (broken pyproject/manifest) excluding it from get_filesystem_plugins(); case-sensitive key mismatch in URL.","solutions":["Verify the exact plugin key on the plugins list page and correct the URL.","Confirm the plugin directory exists in the expected plugins location and its manifest is valid so discovery includes it.","Reinstall the plugin (restore directory / install extras) then reload the page.","If the plugin was intentionally removed, discard the stale bookmark/link."],"exampleFix":"// before (url)\n/admin/plugins/detail/singlefile/   # removed plugin\n// after\n/admin/plugins/detail/  # list valid keys, e.g. .../detail/pdf/)","handlingStrategy":"validation","validationCode":"key = 'pdf'  # from URL\nfrom archivebox.plugins.views import plugin_detail_view  # discovery source\nfrom archivebox.misc.plugins import get_filesystem_plugins\nif key not in get_filesystem_plugins():\n    abort_link(key)","typeGuard":"def plugin_available(key: str) -> bool:\n    return key in get_filesystem_plugins()","tryCatchPattern":"try:\n    return plugin_detail_view(request, key=key)\nexcept Http404:\n    return redirect('/admin/plugins/')","preventionTips":["Generate plugin links from the discovered plugin list, not hardcoded keys.","After upgrades, refresh bookmarks/links to removed or renamed plugins.","Fix broken plugin manifests so discovery registers them."],"tags":["django","http404","plugins","admin"],"backgroundTag":"plugin-not-found","analyzedSha":"74564b28220090664f919479e82cbf454125fa34","analyzedAt":"2026-08-28T23:56:51.556Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}