{"record":{"id":"76afc6313e4a1666","repo":"toeverything/AFFiNE","slug":"invalid-database-index-db-must-be-between-0-a","errorCode":null,"errorMessage":"Invalid database index: ${db}, must be between 0 and 11","messagePattern":"Invalid database index: (.+?), must be between 0 and 11","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"packages/backend/server/src/base/redis/instances.ts","lineNumber":45,"sourceCode":"  }\n\n  async onModuleDestroy() {\n    try {\n      await this.quit();\n    } catch {\n      this.disconnect();\n    }\n  }\n\n  override duplicate(override?: Partial<RedisOptions>): IORedis {\n    const client = super.duplicate(override);\n    client.on('error', this.errorHandler);\n    return client;\n  }\n\n  assertValidDBIndex(db: number) {\n    if (db && db > 15) {\n      throw new Error(\n        // Redis allows [0..16) by default\n        // we separate the db for different usages by `this.options.db + [0..4]`\n        `Invalid database index: ${db}, must be between 0 and 11`\n      );\n    }\n  }\n}\n\n@Injectable()\nexport class CacheRedis extends Redis {\n  constructor(config: Config) {\n    super(redisOptions({ ...config.redis, ...config.redis.ioredis }));\n  }\n}\n\n@Injectable()\nexport class SessionRedis extends Redis {\n  constructor(config: Config) {","sourceCodeStart":27,"sourceCodeEnd":63,"githubUrl":"https://github.com/toeverything/AFFiNE/blob/26c515e050211269e911f7d9cfe162a26c83ed98/packages/backend/server/src/base/redis/instances.ts#L27-L63","documentation":"Thrown by Redis.assertValidDBIndex() when a Redis database index greater than 15 is requested. The comment notes Redis allows [0..16) by default, and the app separates different Redis uses (cache, session, socket.io, queue) by offsetting the base db index by 0–4. A db value of 12 or higher would push these offsets past Redis's 16-database limit, so indices above 15 are rejected as invalid.","triggerScenarios":"Constructing a Redis instance (CacheRedis, SessionRedis, SocketIoRedis, QueueRedis) or calling assertValidDBIndex(db) with db > 15. The base config.redis.db value combined with the per-class offset (+2, +3, +4) must stay under 16.","commonSituations":"Setting config.redis.db (or the REDIS_DB env var) to a high value like 13, which when offset by +4 for QueueRedis becomes 17, exceeding the limit. Using a Redis provider that assigns high database indices. Copying config from an environment with different Redis limits.","solutions":["Set config.redis.db to a low value (0–11) so that db + max_offset(4) stays under 16.","Check the REDIS_DB environment variable and reduce it.","If you need more database separation, configure separate Redis instances instead of high db indices."],"exampleFix":"// before (.env)\nREDIS_DB=13 // QueueRedis uses db 13+4=17 -> throws\n\n// after\nREDIS_DB=0 // QueueRedis uses db 0+4=4, all within [0..16)","handlingStrategy":"validation","validationCode":"function validateRedisDb(db: number): void {\n  if (db && db > 11) {\n    throw new Error(`Redis db must be between 0 and 11 (got ${db}). Max offset of +4 must stay under 16.`);\n  }\n}\nvalidateRedisDb(config.redis.db ?? 0);","typeGuard":"const isValidRedisDb = (db: number): boolean => db >= 0 && db <= 11;","tryCatchPattern":null,"preventionTips":["Keep config.redis.db at 0 or a low single-digit value.","Add a startup config check for redis.db before constructing Redis instances.","If you need more isolation, use separate Redis instances rather than high db indices."],"tags":["affine-backend","redis","config","startup","database"],"backgroundTag":null,"analyzedSha":"26c515e050211269e911f7d9cfe162a26c83ed98","analyzedAt":"2026-08-12T13:15:16.447Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}