Mintplex-Labs/anything-llm · error
Device not found
Error message
Device not found
What it means
validDeviceToken resolves the header token with MobileDevice.get({ token }); if no desktop_mobile_devices row has that token it responds 400 { error: 'Device not found' }. On these routes devices are identified by their uuid v4 token (issued at /mobile/register and stored in the DB), not by id.
Source
Thrown at server/endpoints/mobile/middleware/index.js:23
/**
* Validates the device id from the request headers by checking if the device
* exists in the database and is approved.
* @param {import("express").Request} request
* @param {import("express").Response} response
* @param {import("express").NextFunction} next
*/
async function validDeviceToken(request, response, next) {
try {
const token = request.header("x-anythingllm-mobile-device-token");
if (!token)
return response.status(400).json({ error: "Device token is required" });
const device = await MobileDevice.get(
{ token: String(token) },
{ user: true }
);
if (!device)
return response.status(400).json({ error: "Device not found" });
if (!device.approved)
return response.status(400).json({ error: "Device not approved" });
// If the device is associated with a user then we can associate it with the locals
// so we can reuse it later.
if (device.user) {
if (device.user.suspended)
return response.status(400).json({ error: "User is suspended." });
response.locals.user = device.user;
}
delete device.user;
response.locals.device = device;
next();
} catch (error) {
console.error("validDeviceToken", error);
response.status(500).json({ error: "Invalid middleware response" });
}View on GitHub (pinned to 3aec848f28)
Solutions
- Re-register: admin generates fresh connect-info/QR, app POSTs /mobile/register, store the new token
- If the device should still exist, compare the stored token against the DB row (SELECT * FROM desktop_mobile_devices WHERE token = '...')
- After any DB reset, expect all previously issued device tokens to be dead
Example fix
// before
const res = await api.command('workspaces');
if (!res.ok) throw new Error(res.status);
// after
const res = await api.command('workspaces');
if (res.status === 400 && (await res.json()).error === 'Device not found') {
await Storage.remove('deviceToken');
return navigation.reset('PairScreen'); // re-register flow
} Defensive patterns
Strategy: fallback
Try / catch
try {
await api.command('workspaces');
} catch (e) {
if (e.status === 400 && e.body?.error === 'Device not found') {
await clearStoredToken();
return startPairingFlow(); // fallback: re-register for a fresh token
}
throw e;
} Prevention
- Keep the token in durable storage keyed per server base URL
- Never reuse a token across instances or after a DB restore
- Handle 'Device not found' as a distinct branch that resets pairing state
When it happens
Trigger: Using a token whose device row the admin deleted (DELETE /api/mobile/:id); a token truncated or altered in storage/transit; pointing the app at a different backend instance or database that never registered the device.
Common situations: Device revoked by admin while the phone still caches the token; server DB reset or restore wiping desktop_mobile_devices; switching the app between local and hosted AnythingLLM instances.
Related errors
- Device token is required
- Device not found
- Device not approved
- User is suspended.
- Registration token is required
AI-assisted analysis of Mintplex-Labs/anything-llm@3aec848f28 (2026-08-18).
Data as JSON: /api/errors/eb573274ef91ff51.
Report an issue: GitHub.