{"record":{"id":"645e2f05c8eb935e","repo":"redis/node-redis","slug":"tokenmanager-is-not-running-but-received-an-error","errorCode":null,"errorMessage":"TokenManager is not running but received an error: ${errorMessage}","messagePattern":"TokenManager is not running but received an error: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"warning","filePath":"packages/client/lib/authx/token-manager.ts","lineNumber":314,"sourceCode":"    }\n\n    this.listener = null;\n    this.currentToken = null;\n    this.retryAttempt = 0;\n  }\n\n  /**\n   * Returns the current token or null if no token is available.\n   */\n  public getCurrentToken(): Token<T> | null {\n    return this.currentToken;\n  }\n\n  private notifyError(error: unknown, isRetryable: boolean): void {\n    const errorMessage = error instanceof Error ? error.message : String(error);\n\n    if (!this.listener) {\n      throw new Error(`TokenManager is not running but received an error: ${errorMessage}`);\n    }\n\n    this.listener.onError(new IDPError(errorMessage, isRetryable));\n  }\n}","sourceCodeStart":296,"sourceCodeEnd":319,"githubUrl":"https://github.com/redis/node-redis/blob/90fd0652bc3f2a0a1b2f79fa9096b02a86b0ac58/packages/client/lib/authx/token-manager.ts#L296-L319","documentation":"The error-path twin of error 7. notifyError delivers an IDP error to listener.onError; when the listener is null (manager stopped) it throws instead. Triggered when an in-flight requestToken() rejects after stop() has cleared the listener.","triggerScenarios":"stop() called while requestToken() is pending; the request later rejects (network/credentials) and the rejection surfaces through notifyError with no listener attached.","commonSituations":"Teardown during an IDP outage; IDP rejecting concurrently with shutdown; retry timer firing after stop.","solutions":["Await in-flight refresh before stop().","Catch and log this specific error during teardown.","Make stop() cancel pending token requests rather than letting them resolve later."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  await manager.refresh();\n} catch (err) {\n  if (/not running.*error/i.test(err.message)) {\n    // teardown race; safe to ignore\n    return;\n  }\n  throw err;\n}","preventionTips":["Await in-flight refresh before stop().","Treat 'not running but received an error' as a teardown-time signal, not a production failure.","Cancel pending token requests in stop() rather than letting them resolve later."],"tags":["lifecycle","race","token-manager","auth","teardown"],"backgroundTag":null,"analyzedSha":"90fd0652bc3f2a0a1b2f79fa9096b02a86b0ac58","analyzedAt":"2026-08-11T15:37:21.243Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}