Mintplex-Labs/anything-llm · error
Registration token is required
Error message
Registration token is required
What it means
validRegistrationToken guards POST /api/mobile/register. It reads the Authorization header and takes the second space-separated segment as the temporary token; if there is no Authorization header or no token segment, it responds 400 { error: 'Registration token is required' }.
Source
Thrown at server/endpoints/mobile/middleware/index.js:58
response.status(500).json({ error: "Invalid middleware response" });
}
}
/**
* Validates a temporary registration token that is passed in the request
* and associates the user with the token (if valid). Temporary token is consumed
* and cannot be used again after this middleware is called.
* @param {*} request
* @param {*} response
* @param {*} next
*/
async function validRegistrationToken(request, response, next) {
try {
const authHeader = request.header("Authorization");
const tempToken = authHeader ? authHeader.split(" ")[1] : null;
if (!tempToken)
return response
.status(400)
.json({ error: "Registration token is required" });
const tempTokenData = MobileDevice.tempToken(tempToken);
if (!tempTokenData)
return response
.status(400)
.json({ error: "Invalid or expired registration token" });
// If in multi-user mode, we need to validate the user id
// associated exists, is not banned and then associate with locals so we can reuse it later.
// If not in multi-user mode then simply having a valid token is enough.
const multiUserMode = await SystemSettings.isMultiUserMode();
if (multiUserMode) {
if (!tempTokenData.userId)
return response
.status(400)
.json({ error: "User id not found in registration token" });
const user = await User.get({ id: Number(tempTokenData.userId) });View on GitHub (pinned to 3aec848f28)
Solutions
- Send 'Authorization: Bearer <tempToken>' where tempToken is the t query param of the connect-info URL/QR
- Keep the exact 'Bearer ' prefix with a single space
- Parse ?t= from the connection URL before issuing the register request
Example fix
// before
fetch('/api/mobile/register', {
method: 'POST',
headers: { 'x-registration-token': tempToken },
body: JSON.stringify({ deviceOs: 'android', deviceName }),
});
// after
fetch('/api/mobile/register', {
method: 'POST',
headers: {
Authorization: `Bearer ${tempToken}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({ deviceOs: 'android', deviceName }),
}); Defensive patterns
Strategy: validation
Validate before calling
if (!tempToken) throw new Error('No registration token — fetch connect-info first');
const headers = { Authorization: `Bearer ${tempToken}` }; Prevention
- Build the Authorization header in one helper so every register call is uniform
- Extract t= from the connect-info URL before attempting register
- Remember: register uses Authorization Bearer; device routes use the x-anythingllm-mobile-device-token header
When it happens
Trigger: POST /api/mobile/register with no Authorization header, with 'Bearer' but no token, with a raw token lacking the 'Bearer ' prefix (split(' ')[1] is undefined), or with a non-space-separated scheme.
Common situations: Client puts the temp token in a custom header or the JSON body instead of Authorization: Bearer <t>; the t= param from the connect-info URL was never extracted before calling register.
Related errors
- Device token is required
- Device OS and name are required
- Invalid device OS - ${deviceOs}
- Device not found
- Device not approved
AI-assisted analysis of Mintplex-Labs/anything-llm@3aec848f28 (2026-08-18).
Data as JSON: /api/errors/ade9de9943197571.
Report an issue: GitHub.