{"record":{"id":"848de6538a370898","repo":"n8n-io/n8n","slug":"not-authenticated-call-login-first","errorCode":null,"errorMessage":"Not authenticated — call login() first","messagePattern":"Not authenticated — call login\\(\\) first","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/@n8n/instance-ai/evaluations/clients/n8n-client.ts","lineNumber":991,"sourceCode":"\t\t});\n\t}\n\n\t// -- SSE helpers ---------------------------------------------------------\n\n\t/**\n\t * Build the SSE events URL for a given thread.\n\t * Used by the SSE client to open a streaming connection.\n\t */\n\tgetEventsUrl(threadId: string): string {\n\t\treturn `${this.baseUrl}/rest/instance-ai/events/${threadId}`;\n\t}\n\n\t/**\n\t * Expose the session cookie so the SSE client can authenticate.\n\t */\n\tget cookie(): string {\n\t\tif (!this.sessionCookie) {\n\t\t\tthrow new Error('Not authenticated — call login() first');\n\t\t}\n\t\treturn this.sessionCookie;\n\t}\n\n\t// -- Internal fetch ------------------------------------------------------\n\n\tprivate unwrapRestData<T>(result: unknown): T {\n\t\tif (result && typeof result === 'object' && 'data' in result) {\n\t\t\treturn (result as { data: T }).data;\n\t\t}\n\t\treturn result as T;\n\t}\n\n\tprivate async fetch(\n\t\tpath: string,\n\t\toptions: { method?: string; body?: unknown; timeoutMs?: number } = {},\n\t): Promise<unknown> {\n\t\tconst headers: Record<string, string> = { 'Content-Type': 'application/json' };","sourceCodeStart":973,"sourceCodeEnd":1009,"githubUrl":"https://github.com/n8n-io/n8n/blob/5ac6606e81f67bb9534255570cd4e86fd8101eee/packages/@n8n/instance-ai/evaluations/clients/n8n-client.ts#L973-L1009","documentation":"The N8nClient.cookie getter returns sessionCookie for SSE auth, but throws if it was never set (no login). This is a fail-fast guard so SSE callers don't silently send requests with an undefined cookie and get 401s deep in the stream.","triggerScenarios":"Constructing an SSE client and reading `client.cookie` before calling login(); reusing a client after its session expired without re-login.","commonSituations":"Forgetting to login; refactoring that bypasses the login step; long-running processes whose cookie was cleared.","solutions":["Call await client.login() before reading client.cookie.","If reusing a client across a long lifespan, re-login when the cookie is missing.","Guard callers with `if (!client.isAuthenticated) await client.login()`."],"exampleFix":"// before: const sse = new SseClient(client.cookie, ...);\n// after:  await client.login();\n//        const sse = new SseClient(client.cookie, ...);","handlingStrategy":"validation","validationCode":"if (!client.sessionCookie) await client.login();\nconst cookie = client.cookie; // safe after the guard","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Treat login() as a mandatory precondition for any cookie consumer.","Add an isAuthenticated accessor to make the check ergonomic.","Re-login on long-lived processes when the cookie may expire."],"tags":["auth","n8n-api","sse"],"backgroundTag":null,"analyzedSha":"5ac6606e81f67bb9534255570cd4e86fd8101eee","analyzedAt":"2026-08-12T05:26:35.080Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}