[GH-ISSUE #4598] [BUG]: API Key Authentication Not Associating User with Chat Messages #2923

Closed
opened 2026-02-22 18:31:52 -05:00 by yindo · 2 comments
Owner

Originally created by @help4bis on GitHub (Oct 30, 2025).
Original GitHub issue: https://github.com/Mintplex-Labs/anything-llm/issues/4598

Originally assigned to: @shatfield4 on GitHub.

How are you running AnythingLLM?

Docker (local)

What happened?

API Key Authentication Not Associating User with Chat Messages

Summary

When using API key authentication (Bearer token) with the /api/v1/workspace/:slug/chat endpoint, chat messages are saved with user_id = NULL in the database. This causes crashes when chat history grows beyond the context window limit and the message compression logic tries to access the user property.

Environment

  • AnythingLLM Version: latest (Docker image mintplexlabs/anythingllm:latest)
  • Deployment: Docker
  • Authentication Method: API Key (Bearer token)
  • LLM Provider: Ollama
  • Vector DB: LanceDB

Bug Description

Error Message

TypeError: Cannot read properties of undefined (reading 'user')
    at messageArrayCompressor (/app/server/utils/helpers/chat/index.js:67:35)
    at OllamaAILLM.compressMessages (/app/server/utils/AiProviders/ollama/index.js:408:18)
    at Object.chatSync (/app/server/utils/chats/apiChatHandler.js:295:39)
    at async /app/server/endpoints/api/workspace/index.js:681:24

When It Occurs

  1. API calls work fine initially (first ~5-10 messages)
  2. When chat history exceeds context window limit (~4096 tokens for llama3.2-vision)
  3. AnythingLLM attempts to compress message history
  4. Compression logic crashes because user_id is NULL for API-created messages

Database Evidence

-- Messages created via API have NULL user_id
SELECT id, user_id, LENGTH(prompt) FROM workspace_chats ORDER BY id DESC LIMIT 5;

-- Results:
214 | NULL | 33
213 | 1    | 3221  (created via UI)
212 | 1    | 15    (created via UI)
211 | NULL | 25
210 | NULL | 3115

Root Cause

There are two bugs preventing API key authentication from associating users with chat messages:

Bug 1: validApiKey Middleware

File: /app/server/utils/middleware/validApiKey.js

The middleware validates the API key but doesn't load the associated user into response.locals.user:

async function validApiKey(request, response, next) {
  const multiUserMode = await SystemSettings.isMultiUserMode();
  response.locals.multiUserMode = multiUserMode;

  const auth = request.header("Authorization");
  const bearerKey = auth ? auth.split(" ")[1] : null;
  if (!bearerKey) {
    response.status(403).json({
      error: "No valid api key found.",
    });
    return;
  }

  if (!(await ApiKey.get({ secret: bearerKey }))) {
    response.status(403).json({
      error: "No valid api key found.",
    });
    return;
  }

  // BUG: User is not loaded here!
  next();
}

Bug 2: Workspace Endpoint Hardcoded user: null

File: /app/server/endpoints/api/workspace/index.js (lines ~685 and ~838)

The workspace chat endpoint hardcodes user: null instead of using the authenticated user:

const result = await ApiChatHandler.chatSync({
  workspace,
  message,
  mode,
  user: null,  // BUG: Should be response.locals.user
  thread: null,
  sessionId: !!sessionId ? String(sessionId) : null,
  attachments,
  reset,
});

Proposed Fix

Fix 1: Update validApiKey.js

const { ApiKey } = require("../../models/apiKeys");
const { SystemSettings } = require("../../models/systemSettings");
const { User } = require("../../models/user");

async function validApiKey(request, response, next) {
  const multiUserMode = await SystemSettings.isMultiUserMode();
  response.locals.multiUserMode = multiUserMode;

  const auth = request.header("Authorization");
  const bearerKey = auth ? auth.split(" ")[1] : null;
  if (!bearerKey) {
    response.status(403).json({
      error: "No valid api key found.",
    });
    return;
  }

  // Get the API key from database
  const apiKey = await ApiKey.get({ secret: bearerKey });
  if (!apiKey) {
    response.status(403).json({
      error: "No valid api key found.",
    });
    return;
  }

  // FIX: Load the user who created this API key
  if (apiKey.createdBy) {
    const user = await User.get({ id: apiKey.createdBy });
    if (user) {
      response.locals.user = user;
    }
  }

  next();
}

Fix 2: Update workspace/index.js

Change line ~685:

// Before:
user: null,

// After:
user: response.locals.user || null,

Also change line ~838 (similar pattern in different endpoint).

Impact

Severity: High

  • Breaks long conversations via API
  • Affects all API integrations (WordPress plugins, custom apps, etc.)
  • No workaround without modifying source code
  • Error only appears after several messages, making it hard to debug

Affected Users:

  • Anyone using API key authentication for programmatic access
  • WordPress plugins integrating AnythingLLM
  • Custom applications using the REST API

Workaround

Until fixed, manually update the database after each API call:

UPDATE workspace_chats SET user_id = 1 WHERE user_id IS NULL;

Or apply the code fixes manually after each container update.

Additional Context

  • API key table has createdBy field linking to user ID
  • UI-based authentication works correctly
  • Session-based auth may have similar issue (untested)
  • The api_keys table structure supports user association:
CREATE TABLE "api_keys" (
    "id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
    "secret" TEXT,
    "createdBy" INTEGER,  -- Links to users.id
    "createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
    "lastUpdatedAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
);

Test Case

After applying the fix, verify:

  1. API calls properly set user_id in database
  2. Long conversations don't crash
  3. Message compression works correctly
  4. No regression in UI-based chat
# Should succeed without errors
for i in {1..20}; do
  curl -X POST http://localhost:3001/api/v1/workspace/test/chat \
    -H "Authorization: Bearer $API_KEY" \
    -H "Content-Type: application/json" \
    -d "{\"message\": \"Message $i\", \"mode\": \"chat\"}"
  sleep 1
done

Related Files

  • /app/server/utils/middleware/validApiKey.js
  • /app/server/endpoints/api/workspace/index.js
  • /app/server/utils/chats/apiChatHandler.js
  • /app/server/utils/helpers/chat/index.js (where error occurs)

Tested Fix: I've applied these changes to my local instance and confirmed:

  • API calls now properly associate with users
  • Long conversations work without crashes
  • Message compression functions correctly
  • No impact on UI-based authentication

Are there known steps to reproduce?

Steps to Reproduce

  1. Create an API key in AnythingLLM UI
  2. Send API request with Bearer token:
curl -X POST http://localhost:3001/api/v1/workspace/rds-ink/chat \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"message": "Test message 1", "mode": "chat"}'
  1. Repeat 10+ times to build up chat history
  2. Send a long prompt that requires history compression
  3. Expected: Chat response with sources
  4. Actual: Error: Cannot read properties of undefined (reading 'user')
Originally created by @help4bis on GitHub (Oct 30, 2025). Original GitHub issue: https://github.com/Mintplex-Labs/anything-llm/issues/4598 Originally assigned to: @shatfield4 on GitHub. ### How are you running AnythingLLM? Docker (local) ### What happened? # API Key Authentication Not Associating User with Chat Messages ## Summary When using API key authentication (Bearer token) with the `/api/v1/workspace/:slug/chat` endpoint, chat messages are saved with `user_id = NULL` in the database. This causes crashes when chat history grows beyond the context window limit and the message compression logic tries to access the user property. ## Environment - **AnythingLLM Version**: `latest` (Docker image `mintplexlabs/anythingllm:latest`) - **Deployment**: Docker - **Authentication Method**: API Key (Bearer token) - **LLM Provider**: Ollama - **Vector DB**: LanceDB ## Bug Description ### Error Message ``` TypeError: Cannot read properties of undefined (reading 'user') at messageArrayCompressor (/app/server/utils/helpers/chat/index.js:67:35) at OllamaAILLM.compressMessages (/app/server/utils/AiProviders/ollama/index.js:408:18) at Object.chatSync (/app/server/utils/chats/apiChatHandler.js:295:39) at async /app/server/endpoints/api/workspace/index.js:681:24 ``` ### When It Occurs 1. API calls work fine initially (first ~5-10 messages) 2. When chat history exceeds context window limit (~4096 tokens for llama3.2-vision) 3. AnythingLLM attempts to compress message history 4. Compression logic crashes because `user_id` is NULL for API-created messages ### Database Evidence ```sql -- Messages created via API have NULL user_id SELECT id, user_id, LENGTH(prompt) FROM workspace_chats ORDER BY id DESC LIMIT 5; -- Results: 214 | NULL | 33 213 | 1 | 3221 (created via UI) 212 | 1 | 15 (created via UI) 211 | NULL | 25 210 | NULL | 3115 ``` ## Root Cause There are **two bugs** preventing API key authentication from associating users with chat messages: ### Bug 1: `validApiKey` Middleware **File**: `/app/server/utils/middleware/validApiKey.js` The middleware validates the API key but doesn't load the associated user into `response.locals.user`: ```javascript async function validApiKey(request, response, next) { const multiUserMode = await SystemSettings.isMultiUserMode(); response.locals.multiUserMode = multiUserMode; const auth = request.header("Authorization"); const bearerKey = auth ? auth.split(" ")[1] : null; if (!bearerKey) { response.status(403).json({ error: "No valid api key found.", }); return; } if (!(await ApiKey.get({ secret: bearerKey }))) { response.status(403).json({ error: "No valid api key found.", }); return; } // BUG: User is not loaded here! next(); } ``` ### Bug 2: Workspace Endpoint Hardcoded `user: null` **File**: `/app/server/endpoints/api/workspace/index.js` (lines ~685 and ~838) The workspace chat endpoint hardcodes `user: null` instead of using the authenticated user: ```javascript const result = await ApiChatHandler.chatSync({ workspace, message, mode, user: null, // BUG: Should be response.locals.user thread: null, sessionId: !!sessionId ? String(sessionId) : null, attachments, reset, }); ``` ## Proposed Fix ### Fix 1: Update `validApiKey.js` ```javascript const { ApiKey } = require("../../models/apiKeys"); const { SystemSettings } = require("../../models/systemSettings"); const { User } = require("../../models/user"); async function validApiKey(request, response, next) { const multiUserMode = await SystemSettings.isMultiUserMode(); response.locals.multiUserMode = multiUserMode; const auth = request.header("Authorization"); const bearerKey = auth ? auth.split(" ")[1] : null; if (!bearerKey) { response.status(403).json({ error: "No valid api key found.", }); return; } // Get the API key from database const apiKey = await ApiKey.get({ secret: bearerKey }); if (!apiKey) { response.status(403).json({ error: "No valid api key found.", }); return; } // FIX: Load the user who created this API key if (apiKey.createdBy) { const user = await User.get({ id: apiKey.createdBy }); if (user) { response.locals.user = user; } } next(); } ``` ### Fix 2: Update `workspace/index.js` Change line ~685: ```javascript // Before: user: null, // After: user: response.locals.user || null, ``` Also change line ~838 (similar pattern in different endpoint). ## Impact **Severity**: High - Breaks long conversations via API - Affects all API integrations (WordPress plugins, custom apps, etc.) - No workaround without modifying source code - Error only appears after several messages, making it hard to debug **Affected Users**: - Anyone using API key authentication for programmatic access - WordPress plugins integrating AnythingLLM - Custom applications using the REST API ## Workaround Until fixed, manually update the database after each API call: ```sql UPDATE workspace_chats SET user_id = 1 WHERE user_id IS NULL; ``` Or apply the code fixes manually after each container update. ## Additional Context - API key table has `createdBy` field linking to user ID - UI-based authentication works correctly - Session-based auth may have similar issue (untested) - The `api_keys` table structure supports user association: ```sql CREATE TABLE "api_keys" ( "id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, "secret" TEXT, "createdBy" INTEGER, -- Links to users.id "createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, "lastUpdatedAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ); ``` ## Test Case After applying the fix, verify: 1. API calls properly set `user_id` in database 2. Long conversations don't crash 3. Message compression works correctly 4. No regression in UI-based chat ```bash # Should succeed without errors for i in {1..20}; do curl -X POST http://localhost:3001/api/v1/workspace/test/chat \ -H "Authorization: Bearer $API_KEY" \ -H "Content-Type: application/json" \ -d "{\"message\": \"Message $i\", \"mode\": \"chat\"}" sleep 1 done ``` ## Related Files - `/app/server/utils/middleware/validApiKey.js` - `/app/server/endpoints/api/workspace/index.js` - `/app/server/utils/chats/apiChatHandler.js` - `/app/server/utils/helpers/chat/index.js` (where error occurs) --- **Tested Fix**: I've applied these changes to my local instance and confirmed: - ✅ API calls now properly associate with users - ✅ Long conversations work without crashes - ✅ Message compression functions correctly - ✅ No impact on UI-based authentication ### Are there known steps to reproduce? ## Steps to Reproduce 1. Create an API key in AnythingLLM UI 2. Send API request with Bearer token: ```bash curl -X POST http://localhost:3001/api/v1/workspace/rds-ink/chat \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{"message": "Test message 1", "mode": "chat"}' ``` 3. Repeat 10+ times to build up chat history 4. Send a long prompt that requires history compression 5. **Expected**: Chat response with sources 6. **Actual**: Error: `Cannot read properties of undefined (reading 'user')`
yindo added the possible bug label 2026-02-22 18:31:52 -05:00
yindo closed this issue 2026-02-22 18:31:52 -05:00
Author
Owner

@dragonflybookworks commented on GitHub (Nov 19, 2025):

I am having this issue too, but anytime I try to use Llama3.1:8b-gradient via Ollama in AnythingLLM workspaces. I need the expanded context tokens that gradient provides, but it returns the "Cannot read properties of undefined (reading 'user')" right from the start (as in, when I just say "hello"). I discovered that constantly resetting the vector database at the start of each session fixes the issue....

@dragonflybookworks commented on GitHub (Nov 19, 2025): I am having this issue too, but anytime I try to use Llama3.1:8b-gradient via Ollama in AnythingLLM workspaces. I need the expanded context tokens that gradient provides, but it returns the "Cannot read properties of undefined (reading 'user')" right from the start (as in, when I just say "hello"). I discovered that constantly resetting the vector database at the start of each session fixes the issue....
Author
Owner

@timothycarambat commented on GitHub (Nov 21, 2025):

resolved by #4669 - which was caused by a race condition due to us trying to determine the token context window size for your loaded model. This is now patched.

It comes from this line
https://github.com/Mintplex-Labs/anything-llm/blob/4ec85418c448a2c0e7b565c8b43c54dff668d53b/server/utils/helpers/chat/index.js#L67-L68

Which only becomes relevant when you are estimated to have more content in your chat window than the model can support and we have to begin truncation. This specifically impacted both Ollama and LM Studio

@timothycarambat commented on GitHub (Nov 21, 2025): resolved by #4669 - which was caused by a race condition due to us trying to determine the token context window size for your loaded model. This is now patched. It comes from this line https://github.com/Mintplex-Labs/anything-llm/blob/4ec85418c448a2c0e7b565c8b43c54dff668d53b/server/utils/helpers/chat/index.js#L67-L68 Which only becomes relevant when you are estimated to have more content in your chat window than the model can support and we have to begin truncation. This specifically impacted both Ollama and LM Studio
yindo changed title from [BUG]: API Key Authentication Not Associating User with Chat Messages to [GH-ISSUE #4598] [BUG]: API Key Authentication Not Associating User with Chat Messages 2026-06-05 14:49:18 -04:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: Mintplex-Labs/anything-llm#2923