Skip to content
This repository was archived by the owner on Jun 16, 2026. It is now read-only.

fix(auth): prevent caching of failed backend instances in getStorageBackend#9237

Open
Sandeep6135 wants to merge 3 commits into
SandeepVashishtha:masterfrom
Sandeep6135:fix/user-storage-cached-failed-instance
Open

fix(auth): prevent caching of failed backend instances in getStorageBackend#9237
Sandeep6135 wants to merge 3 commits into
SandeepVashishtha:masterfrom
Sandeep6135:fix/user-storage-cached-failed-instance

Conversation

@Sandeep6135

Copy link
Copy Markdown
Contributor

Pull Request: Prevent Caching of Failed Storage Backend Instances

🚨 Severity & Classification


📝 Problem Summary

In the user storage abstraction factory (api/auth/_user-storage.js), the getStorageBackend function was assigning the instantiated class instance to the global/module-scoped storageBackend variable before executing the asynchronous .initialize() call:

// Before Fix
storageBackend = new RedisStorageBackend(databaseUrl);
await storageBackend.initialize(); // If this throws, storageBackend remains cached as a broken instance!
return storageBackend;

If initialization fails (e.g. database network drops, invalid configuration, connection timeout), the exception is thrown, but the failed, uninitialized instance remains cached in storageBackend.

On all subsequent requests, getStorageBackend() checks if (storageBackend) { return storageBackend; } and immediately returns the broken instance without attempting to re-initialize or retry connection. This causes the entire application authentication layer to remain permanently broken even after the database recovers.


🛠️ Solution Overview

1. Safe Initialization Pattern (Delayed Assignment)

Refactored getStorageBackend() in api/auth/_user-storage.js to instantiate and initialize the backend within a local variable. The global storageBackend variable is only assigned after the asynchronous initialization completes successfully:

// After Fix
const backend = new RedisStorageBackend(databaseUrl);
await backend.initialize();
storageBackend = backend; // Assigned only on successful connection/init
return storageBackend;

If .initialize() fails, the global storageBackend remains null. Next calls will trigger a fresh initialization attempt, allowing the application to self-heal and reconnect.

2. Base Class Exports & Imports Cleanup

  • Exported the base class StorageBackend from api/auth/_user-storage.js so it can be verified in unit tests.
  • Corrected imports in src/__tests__/user-storage.test.js to point to _user-storage.js (with an underscore) instead of the public route path, complying with Vercel's internal file convention.

3. Factory Caching Integrity Test Case

Added a test case should not cache failed storage backend instance on initialization failure to src/__tests__/user-storage.test.js:

  • Attempts to initialize the storage backend with a broken Redis connection string.
  • Verifies that it throws an initialization error.
  • Corrects the configuration and verifies that the second initialization attempt successfully builds a new working backend (proving that the failed instance was not cached).

🧪 Verification Results

All 22 unit tests for the user-storage abstraction pass successfully:

npx vitest run src/__tests__/user-storage.test.js
  • Result: Test Files: 1 passed | Tests: 22 passed | Duration: ~4.5s

@vercel

vercel Bot commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

@Sandeep6135 is attempting to deploy a commit to the sandeepvashishtha's projects Team on Vercel.

A member of the Team first needs to authorize it.

codescene-access[bot]

This comment was marked as outdated.

@Sandeep6135 Sandeep6135 force-pushed the fix/user-storage-cached-failed-instance branch from b5ef3d1 to 2253be4 Compare June 16, 2026 06:21
codescene-access[bot]

This comment was marked as outdated.

@Sandeep6135 Sandeep6135 force-pushed the fix/user-storage-cached-failed-instance branch from 2253be4 to e4681a3 Compare June 16, 2026 06:30
@github-actions github-actions Bot added quality:clean 1.2x size/XL Extra-large pull request and removed quality:exceptional 1.5x labels Jun 16, 2026

@codescene-access codescene-access Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Gates Failed
New code is healthy (4 new files with code health below 10.00)
Enforce advisory code health rules (4 files with Complex Method, Complex Conditional, Overall Code Complexity)

Our agent can fix these. Install it.

Gates Passed
2 Quality Gates Passed

Reason for failure
New code is healthy Violations Code Health Impact
signup.js 2 rules 8.67 Suppress
_user-storage.js 1 rule 9.18 Suppress
reauth.js 2 rules 9.39 Suppress
login.js 1 rule 9.53 Suppress
Enforce advisory code health rules Violations Code Health Impact
signup.js 2 advisory rules 8.67 Suppress
_user-storage.js 1 advisory rule 9.18 Suppress
reauth.js 2 advisory rules 9.39 Suppress
login.js 1 advisory rule 9.53 Suppress

See analysis details in CodeScene

Quality Gate Profile: Clean Code Collective
Install CodeScene MCP: safeguard and uplift AI-generated code. Catch issues early with our IDE extension and CLI tool.

Comment thread api/auth/_user-storage.js
Comment thread api/auth/_user-storage.js
Comment thread api/auth/_user-storage.js
Comment thread api/auth/login.js
Comment thread api/auth/reauth.js
Comment thread api/auth/reauth.js
Comment thread api/auth/signup.js
Comment thread api/auth/signup.js
Comment thread api/auth/signup.js
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

BUG: Permanently Cached Failed Instance in User Storage Factory (High)

1 participant