{"record":{"id":"b53d8a56d3e852f4","repo":"TencentCloud/TencentDB-Agent-Memory","slug":"key-limit-exceeded","errorCode":"key_limit_exceeded","errorMessage":"active user key limit ${this.maxActiveUserKeys} reached","messagePattern":"active user key limit (.+?) reached","errorType":"error_code","errorClass":"MetadataError","httpStatus":null,"severity":"error","filePath":"MemoryCore/src/metadata/service/metadata-service.ts","lineNumber":692,"sourceCode":"      name: entity.name ?? null,\n      status: entity.status,\n      is_default: entity.is_default,\n      last_used_at: entity.last_used_at ?? null,\n      expires_at: entity.expires_at ?? null,\n      created_at: entity.created_at,\n      revoked_at: entity.revoked_at ?? null,\n    };\n  }\n\n  async createUserKey(\n    userId: string,\n    input: { name?: string | null; expires_at?: string | null },\n  ): Promise<UserKeyCreated> {\n    await this.requireUser(userId);\n\n    const active = await this.store.countActiveUserKeys(userId);\n    if (active >= this.maxActiveUserKeys) {\n      throw new MetadataError(\"key_limit_exceeded\", `active user key limit ${this.maxActiveUserKeys} reached`);\n    }\n\n    const entity = await this.store.createUserKey({\n      user_id: userId,\n      name: input.name,\n      expires_at: input.expires_at,\n      is_default: false,\n    });\n    return { ...this.toPublicUserKey(entity), key_value: entity.key_value };\n  }\n\n  async listUserKeys(userId: string, pagination: PaginationParams = DEFAULT_PAGINATION): Promise<PaginatedResult<UserKeyPublic>> {\n    await this.requireUser(userId);\n    const page = await this.store.listUserKeys(userId, pagination);\n    const items = page.items.map((k) => this.toPublicUserKey(k));\n    return formatListResult({ items, total: page.total }, pagination);\n  }\n","sourceCodeStart":674,"sourceCodeEnd":710,"githubUrl":"https://github.com/TencentCloud/TencentDB-Agent-Memory/blob/3efcd317b84146d6a08518ac0f7ee7c8a8d200ec/MemoryCore/src/metadata/service/metadata-service.ts#L674-L710","documentation":"MetadataError code 'key_limit_exceeded' thrown when creating a user API key if the user already has the maximum allowed active keys. The service counts the user's non-revoked, non-expired keys via countActiveUserKeys and compares against this.maxActiveUserKeys; at or above the limit, new key creation is refused. This is a quota guard against unbounded key proliferation.","triggerScenarios":"Calling the user-key creation method (guarded by requireUser) when countActiveUserKeys(userId) >= maxActiveUserKeys — i.e. creating one more key than the configured cap of active keys per user.","commonSituations":"Automation scripts that mint a new key on each deploy without revoking old ones; users rotating keys by creating first and forgetting to revoke; a lowered maxActiveUserKeys config that makes previously-fine key counts exceed the new limit; long-lived keys accumulating over the account's lifetime.","solutions":["Revoke or delete unused active keys for the user (e.g. list keys, revoke the oldest) and retry creation.","Increase the maxActiveUserKeys limit in the service configuration if the quota is genuinely too low.","Implement key rotation as revoke-then-create (or create-then-revoke in one flow) instead of create-only.","Catch MetadataError code 'key_limit_exceeded' and prompt the user to clean up keys in the UI."],"exampleFix":"// before\nawait service.createUserKeyForCaller(userId, ctx, { name: 'ci' }); // limit hit\n// after\nconst keys = await service.listUserKeysForCaller(userId, ctx);\nfor (const k of keys.items.filter(k => k.name.startsWith('ci-')).slice(0, 1)) {\n  await service.revokeUserKeyForCaller(k.id, ctx);\n}\nawait service.createUserKeyForCaller(userId, ctx, { name: 'ci' });","handlingStrategy":"try-catch","validationCode":"const active = await store.countActiveUserKeys(userId);\nif (active >= maxActiveUserKeys) { /* revoke first */ }","typeGuard":null,"tryCatchPattern":"try {\n  await service.createUserKeyForCaller(userId, ctx, input);\n} catch (e) {\n  if (e instanceof MetadataError && e.code === 'key_limit_exceeded') { /* revoke oldest active key, then retry once */ }\n  throw e;\n}","preventionTips":["Adopt rotate-on-create: create the new key and revoke the superseded one in the same flow","Track active key counts per user in your app and warn before hitting the cap","Reconcile maxActiveUserKeys config changes with existing key counts","Schedule cleanup of unused/expired keys"],"tags":["quota","key-management","rate-limit"],"backgroundTag":"quota-limit-exceeded","analyzedSha":"3efcd317b84146d6a08518ac0f7ee7c8a8d200ec","analyzedAt":"2026-09-01T05:44:22.276Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}