diff --git a/canvas/src/components/tabs/FilesTab/__tests__/NotAvailablePanel.test.tsx b/canvas/src/components/tabs/FilesTab/__tests__/NotAvailablePanel.test.tsx
new file mode 100644
index 00000000..50a794b2
--- /dev/null
+++ b/canvas/src/components/tabs/FilesTab/__tests__/NotAvailablePanel.test.tsx
@@ -0,0 +1,49 @@
+// @vitest-environment jsdom
+/**
+ * Tests for NotAvailablePanel — full-tab placeholder for unsupported runtimes.
+ *
+ * Coverage:
+ * - Renders heading "Files not available"
+ * - Renders runtime name in monospace span
+ * - Renders helper text referencing Chat tab
+ * - SVG icon is aria-hidden
+ * - Different runtime names display correctly
+ */
+import React from "react";
+import { render, screen, cleanup } from "@testing-library/react";
+import { afterEach, describe, expect, it } from "vitest";
+import { NotAvailablePanel } from "../NotAvailablePanel";
+
+afterEach(cleanup);
+
+describe("NotAvailablePanel", () => {
+ it("renders heading 'Files not available'", () => {
+ render();
+ expect(screen.getByText("Files not available")).toBeTruthy();
+ });
+
+ it("renders the runtime name in monospace", () => {
+ render();
+ expect(screen.getByText("external")).toBeTruthy();
+ const runtimeSpan = screen.getByText("external");
+ expect(runtimeSpan.tagName.toLowerCase()).toBe("span");
+ });
+
+ it("renders helper text referencing Chat tab", () => {
+ render();
+ expect(screen.getByText(/chat tab/i)).toBeTruthy();
+ });
+
+ it("renders SVG icon as aria-hidden", () => {
+ render();
+ const svg = document.querySelector("svg");
+ expect(svg?.getAttribute("aria-hidden")).toBe("true");
+ });
+
+ it("displays different runtime names correctly", () => {
+ render();
+ expect(screen.getByText("hermes")).toBeTruthy();
+ // "runtime" appears in the text node after the hermes span
+ expect(screen.getByText(/runtime, whose filesystem/i)).toBeTruthy();
+ });
+});