{"record":{"id":"73c57b37a77f1a5d","repo":"thedotmack/claude-mem","slug":"claude-mem-redis-url-must-use-redis-or-rediss","errorCode":null,"errorMessage":"CLAUDE_MEM_REDIS_URL must use redis:// or rediss://","messagePattern":"CLAUDE_MEM_REDIS_URL must use redis:// or rediss://","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/server/queue/redis-config.ts","lineNumber":96,"sourceCode":"\nfunction sanitizePrefix(value: string): string {\n  return (value.trim() || 'claude_mem').replace(/[^a-zA-Z0-9_-]/g, '_');\n}\n\nfunction connectionFromHost(host: string, port: number): RedisOptions {\n  return {\n    host,\n    port,\n    maxRetriesPerRequest: null,\n    connectTimeout: 1000,\n    lazyConnect: true,\n  };\n}\n\nfunction connectionFromUrl(rawUrl: string): RedisOptions {\n  const parsed = new URL(rawUrl);\n  if (parsed.protocol !== 'redis:' && parsed.protocol !== 'rediss:') {\n    throw new Error('CLAUDE_MEM_REDIS_URL must use redis:// or rediss://');\n  }\n  const db = parsed.pathname.length > 1\n    ? Number.parseInt(parsed.pathname.slice(1), 10)\n    : undefined;\n  if (db !== undefined && (!Number.isInteger(db) || db < 0)) {\n    throw new Error(`Invalid Redis database in CLAUDE_MEM_REDIS_URL: ${parsed.pathname}`);\n  }\n  return {\n    host: parsed.hostname || '127.0.0.1',\n    port: parsed.port ? Number.parseInt(parsed.port, 10) : 6379,\n    username: parsed.username ? decodeURIComponent(parsed.username) : undefined,\n    password: parsed.password ? decodeURIComponent(parsed.password) : undefined,\n    db,\n    tls: parsed.protocol === 'rediss:' ? {} : undefined,\n    maxRetriesPerRequest: null,\n    connectTimeout: 1000,\n    lazyConnect: true,\n  };","sourceCodeStart":78,"sourceCodeEnd":114,"githubUrl":"https://github.com/thedotmack/claude-mem/blob/d8bc9755e74915e5c3b999181e10a67c889bce2a/src/server/queue/redis-config.ts#L78-L114","documentation":"Thrown by connectionFromUrl when CLAUDE_MEM_REDIS_URL parses as a URL but its protocol is neither redis: nor rediss:. The library only knows how to build an ioredis-style RedisOptions object from redis:// or rediss:// endpoints, and it rejects other schemes up front instead of producing a broken connection config.","triggerScenarios":"CLAUDE_MEM_REDIS_URL set to http://..., https://..., tcp://..., unix:///path/to/sock, or a bare 'localhost:6379' (which URL-parses with a non-redis protocol or fails earlier). Triggered whenever the queue config resolves a URL-based Redis connection.","commonSituations":"Copying a connection string from a web dashboard (often https://) instead of the Redis endpoint; using a Heroku/Render REDIS_URL that starts with redis:// is fine but an HTTP health-check URL is not; including the variable with a placeholder like https://example.com; pointing at a Unix socket path where the library expects TCP URLs.","solutions":["Use a redis:// or rediss:// URL, e.g. redis://localhost:6379/0 or rediss://user:pass@host:6380","For TLS endpoints use the rediss:// scheme (two s), not https://","If you have a socket path, run Redis on TCP or check the library docs for socket support — do not put unix:// in this variable","Re-check that the value was not overwritten by another service's URL (e.g. a generic REDIS_URL copy mistake)"],"exampleFix":"// before (.env)\nCLAUDE_MEM_REDIS_URL=https://my-redis.example.com:6379\n// after\nCLAUDE_MEM_REDIS_URL=redis://my-redis.example.com:6379/0","handlingStrategy":"validation","validationCode":"const url = process.env.CLAUDE_MEM_REDIS_URL;\nif (url) {\n  const parsed = new URL(url);\n  if (parsed.protocol !== 'redis:' && parsed.protocol !== 'rediss:') {\n    throw new Error(`CLAUDE_MEM_REDIS_URL must start with redis:// or rediss://; got ${parsed.protocol}//`);\n  }\n}","typeGuard":"function isRedisUrl(v: string): boolean {\n  try {\n    const p = new URL(v);\n    return p.protocol === 'redis:' || p.protocol === 'rediss:';\n  } catch {\n    return false;\n  }\n}","tryCatchPattern":"try {\n  const config = getRedisQueueConfig();\n} catch (err) {\n  if (err instanceof Error && err.message.includes('must use redis:// or rediss://')) {\n    console.error('Use a redis:// or rediss:// endpoint URL, not an http(s):// or socket URL');\n  }\n  throw err;\n}","preventionTips":["Distinguish dashboard URLs (https://) from Redis endpoints (redis://) when copying from cloud consoles","Use rediss:// (double s) for TLS endpoints","Keep REDIS_URL and health-check/HTTP URLs in separate variables","Validate URL scheme with new URL() in a startup config check"],"tags":["configuration","redis","url","validation"],"backgroundTag":"invalid-url-format","analyzedSha":"d8bc9755e74915e5c3b999181e10a67c889bce2a","analyzedAt":"2026-09-17T16:40:26.182Z","contentChangedAt":"2026-09-17T16:40:26.182Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}