Mintplex-Labs/anything-llm · warning
Bad Request
Error message
Bad Request
What it means
Returned by POST /export-chat/:type when the `:type` URL parameter is not in the validExportTypes list. Line 41-42 checks `if (!validExportTypes.includes(type)) return response.sendStatus(400).end()`. The valid types are defined in server/utils/chats/exportChatToFile.js line 8 as ['pdf', 'markdown', 'plaintext', 'json', 'html']. Any other value — including common variants like 'csv', 'txt', 'JSON', 'JSONL' — is rejected. The check is case-sensitive.
Source
Thrown at server/endpoints/utils.js:42
vectorDB: process.env.VECTOR_DB || "lancedb",
storage: await getDiskStorage(),
appVersion: getDeploymentVersion(),
};
response.status(200).json(metrics);
} catch (e) {
console.error(e);
response.sendStatus(500).end();
}
});
app.post(
"/export-chat/:type",
[validatedRequest, flexUserRoleValid([ROLES.all])],
async (request, response) => {
try {
const { type } = request.params;
if (!validExportTypes.includes(type))
return response.sendStatus(400).end();
const { workspaceSlug, threadSlug } = reqBody(request);
const { Workspace } = require("../models/workspace");
const { WorkspaceThread } = require("../models/workspaceThread");
const { WorkspaceChats } = require("../models/workspaceChats");
const user = await userFromSession(request, response);
const workspace = multiUserMode(response)
? await Workspace.getWithUser(user, { slug: String(workspaceSlug) })
: await Workspace.get({ slug: String(workspaceSlug) });
if (!workspace) return response.sendStatus(404).end();
let thread;
if (threadSlug) {
thread = await WorkspaceThread.get({
slug: String(threadSlug),
user_id: user?.id || null,
});View on GitHub (pinned to 526360e320)
Solutions
- Ensure the :type parameter is exactly one of: 'pdf', 'markdown', 'plaintext', 'json', 'html' (all lowercase).
- Check the frontend export component for the list of types it sends and align it with the backend's validExportTypes constant.
- If case insensitivity is desired, normalize the type to lowercase before validation (requires a backend code change).
- Inspect the actual request URL in the network tab to confirm the type value being sent.
Example fix
// before — wrong/case-mismatch type
await fetch('/export-chat/JSON', { method: 'POST', body: JSON.stringify({ workspaceSlug }) });
// after — lowercase, valid type
const VALID_TYPES = ['pdf', 'markdown', 'plaintext', 'json', 'html'];
const type = String(userChoice).toLowerCase();
if (!VALID_TYPES.includes(type)) throw new Error(`Invalid export type: ${type}`);
await fetch(`/export-chat/${type}`, { method: 'POST', body: JSON.stringify({ workspaceSlug }) }); Defensive patterns
Strategy: validation
Validate before calling
const VALID_EXPORT_TYPES = ['pdf', 'markdown', 'plaintext', 'json', 'html'];
function validateExportType(type) {
const normalized = String(type).toLowerCase();
if (!VALID_EXPORT_TYPES.includes(normalized)) {
throw new Error(
`Invalid export type '${type}'. Must be one of: ${VALID_EXPORT_TYPES.join(', ')}`
);
}
return normalized;
}
// Usage
const type = validateExportType(userSelectedType);
await fetch(`/export-chat/${type}`, { method: 'POST', body: JSON.stringify({ workspaceSlug }) }); Type guard
function isValidExportType(type) {
const VALID = ['pdf', 'markdown', 'plaintext', 'json', 'html'];
return typeof type === 'string' && VALID.includes(type.toLowerCase());
} Prevention
- Always validate the export type against the allowed list before constructing the URL.
- Normalize the type to lowercase client-side to avoid case-sensitivity issues.
- Keep the frontend's export type list in sync with the backend's validExportTypes constant.
- Watch for typos like 'makrdown' or 'pdf ' (trailing space).
When it happens
Trigger: The :type path parameter is a value not in the allowed list: 'csv', 'txt', 'jsonl', 'JSON' (uppercase), 'PDF' (uppercase), or a typo like 'makrdown'. The frontend export menu sends a type identifier that doesn't match the backend's constant.
Common situations: Frontend and backend are out of sync — the frontend offers a format (e.g., 'csv') that the backend doesn't support. Case mismatch: client sends 'JSON' but the backend expects lowercase 'json'. A typo in the type string. URL construction bug that mangles the type segment.
Related errors
- Bad Request
- Invalid video id!
- Impossible to retrieve Youtube video ID.
- Filename is required!
- Invalid scope: ${JSON.stringify(v)}
AI-assisted analysis of Mintplex-Labs/anything-llm@526360e320 (2026-08-13).
Data as JSON: /api/errors/1a3bef2fcfdba31a.
Report an issue: GitHub.