Stirling-Tools/Stirling-PDF · error · Error

IndexedDB context not available

Error message

IndexedDB context not available

What it means

Thrown by `convertToFile` in useFileManager when the `indexedDB` context value is null. The IndexedDB provider (which exposes loadFile/saveFile) is not available in the React tree above this hook — meaning file persistence is offline, so any file conversion/load is impossible.

Source

Thrown at frontend/editor/src/core/hooks/useFileManager.ts:83

          "rtf",
          "html",
          "epub",
        ];
        for (const ext of knownInnerExt) {
          if (lowerName.endsWith(`.${ext}.zip`)) {
            return fallback.slice(0, fallback.length - 4) || fallback;
          }
        }
      }
      return fallback;
    },
    [],
  );

  const convertToFile = useCallback(
    async (fileStub: StirlingFileStub): Promise<File> => {
      if (!indexedDB) {
        throw new Error("IndexedDB context not available");
      }

      // Regular file loading
      if (fileStub.id) {
        const file = await indexedDB.loadFile(fileStub.id);
        if (file) {
          return file;
        }
      }
      throw new Error(
        `File not found in storage: ${fileStub.name} (ID: ${fileStub.id})`,
      );
    },
    [indexedDB],
  );

  const loadRecentFiles = useCallback(async (): Promise<StirlingFileStub[]> => {
    setLoading(true);

View on GitHub (pinned to 9ef20dcab8)

Solutions

  1. Ensure useFileManager consumers are always descendants of the IndexedDBProvider in the component tree.
  2. Detect IndexedDB availability up front and show a user-facing 'storage unavailable' state instead of letting operations throw.
  3. Provide a memory-only fallback storage implementation when IndexedDB is absent (if the product tolerates it).
  4. Add a test wrapper that mounts the provider so this never regresses.

Example fix

// before
const convertToFile = useCallback(async (fileStub) => {
  if (!indexedDB) throw new Error("IndexedDB context not available");
  ...
}, [indexedDB]);

// after — fail fast at hook init with a typed error
if (!indexedDB) {
  throw new Error("IndexedDB context not available — mount IndexedDBProvider above useFileManager consumers.");
}
Defensive patterns

Strategy: validation

Validate before calling

// Ensure the provider is present before using the hook
if (!indexedDB) {
  // render a 'storage unavailable' state instead of calling convertToFile
}

Type guard

function hasIndexedDB(ctx: unknown): ctx is { loadFile: (id: string) => Promise<File | null>; saveFile: (f: File, id: string) => Promise<unknown> } {
  return !!ctx && typeof (ctx as { loadFile?: unknown }).loadFile === "function";
}

Prevention

When it happens

Trigger: useFileManager (or a consumer) is rendered outside the IndexedDBProvider; the provider failed to mount; the context value is intentionally null in an environment without IndexedDB (SSR, restricted iframe with storage disabled).

Common situations: Component tree refactored so a consumer of useFileManager is mounted above the provider; running in a privacy mode / cookie-blocking iframe where IndexedDB is unavailable; testing without wrapping the provider.

Related errors


AI-assisted analysis of Stirling-Tools/Stirling-PDF@9ef20dcab8 (2026-08-13). Data as JSON: /api/errors/ed73efaea951f3e0. Report an issue: GitHub.