[BUG]: API Key Authentication Not Associating User with Chat Messages
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 imagemintplexlabs/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
- API calls work fine initially (first ~5-10 messages)
- When chat history exceeds context window limit (~4096 tokens for llama3.2-vision)
- AnythingLLM attempts to compress message history
- Compression logic crashes because
user_idis 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
createdByfield linking to user ID - UI-based authentication works correctly
- Session-based auth may have similar issue (untested)
- The
api_keystable 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:
- API calls properly set
user_idin database - Long conversations don't crash
- Message compression works correctly
- 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
- Create an API key in AnythingLLM UI
- 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"}'
- Repeat 10+ times to build up chat history
- Send a long prompt that requires history compression
- Expected: Chat response with sources
- Actual: Error:
Cannot read properties of undefined (reading 'user')