{"record":{"id":"f73552031ab730b0","repo":"medusajs/medusa","slug":"caching-redis-redisurl-is-required","errorCode":null,"errorMessage":"[caching-redis] redisUrl is required","messagePattern":"\\[caching-redis\\] redisUrl is required","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"critical","filePath":"packages/modules/providers/caching-redis/src/loaders/connection.ts","lineNumber":39,"sourceCode":"): Promise<void> => {\n  const logger_ = logger || console\n\n  const moduleOptions = (options ??\n    moduleDeclaration?.options ??\n    {}) as RedisCacheModuleOptions\n\n  const {\n    redisUrl,\n    redisOptions: newRedisOptions,\n    // Module options, not ioredis options. Pulled out so they are not\n    // forwarded to the client along with the deprecated top-level options.\n    ttl: _ttl,\n    prefix: _prefix,\n    compressionThreshold: _compressionThreshold,\n    ...deprecatedRedisOptions\n  } = moduleOptions\n  if (!redisUrl) {\n    throw new Error(\"[caching-redis] redisUrl is required\")\n  }\n\n  // Handle backward compatibility for deprecated options\n  if (!newRedisOptions && Object.keys(deprecatedRedisOptions).length) {\n    logger_.warn(\n      \"[caching-redis] Passing ioredis options at the top level of the module options is deprecated. Please use `redisOptions` instead for consistency with other modules.\"\n    )\n  }\n\n  let redisClient: Redis\n\n  const redisOptions: RedisOptions = {\n    connectTimeout: 10000,\n    commandTimeout: 5000,\n    lazyConnect: true,\n    maxRetriesPerRequest: 3,\n    enableOfflineQueue: true,\n    connectionName: \"medusa-cache-redis\",","sourceCodeStart":21,"sourceCodeEnd":57,"githubUrl":"https://github.com/medusajs/medusa/blob/5e06e544a296b9033f20f71f11c559f81a0e5739/packages/modules/providers/caching-redis/src/loaders/connection.ts#L21-L57","documentation":"The caching-redis module loader destructures redisUrl from its options and throws a plain Error if it is falsy. Without a connection string the Redis cache cannot be created, so the module fails at load time.","triggerScenarios":"Registering the Redis cache module in medusa-config.js without a redisUrl option, or with redisUrl: process.env.REDIS_URL where REDIS_URL is unset in that environment.","commonSituations":"REDIS_URL set locally but missing in the deployment/CI environment; renaming from the deprecated top-level ioredis options and forgetting the new key; the value lives in a .env file that isn't loaded (wrong cwd, docker env not passed).","solutions":["Add redisUrl (e.g. redis://default:password@host:6379) to the cacheModule options in medusa-config.js.","If using env vars, confirm REDIS_URL is exported where Medusa runs (docker-compose environment:, deploy secrets) and restart.","Prefer the redisOptions key for any ioredis extras — top-level ioredis options are deprecated and trigger an additional warning."],"exampleFix":"// before\n{ module: ModuleRegistrationKey.CACHE, resolve: \"@medusajs/cache-redis\", options: {} }\n// after\n{ module: ModuleRegistrationKey.CACHE, resolve: \"@medusajs/cache-redis\", options: { redisUrl: process.env.REDIS_URL } }","handlingStrategy":"validation","validationCode":"if (!process.env.REDIS_URL) {\n  throw new Error(\"REDIS_URL must be set when using @medusajs/cache-redis\")\n}","typeGuard":"const hasRedisUrl = (o: { redisUrl?: string } | undefined): o is { redisUrl: string } =>\n  typeof o?.redisUrl === \"string\" && o.redisUrl.length > 0","tryCatchPattern":null,"preventionTips":["Add REDIS_URL to deployment templates and CI secrets.","Fail fast on boot: check the env var before registering the module.","Use the redisOptions key for ioredis extras to avoid deprecation warnings."],"tags":["redis","cache","configuration","startup","connection-string"],"backgroundTag":"missing-connection-string","analyzedSha":"5e06e544a296b9033f20f71f11c559f81a0e5739","analyzedAt":"2026-08-27T07:24:39.599Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}