{"record":{"id":"d09933ae5f938c58","repo":"RocketChat/Rocket.Chat","slug":"invalid-token-d09933","errorCode":null,"errorMessage":"invalid-token","messagePattern":"invalid-token","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"apps/meteor/server/api/v1/omnichannel/customField.ts","lineNumber":30,"sourceCode":"\tvalidateUnauthorizedErrorResponse,\n} from '@rocket.chat/rest-typings';\n\nimport { API } from '../..';\nimport { setCustomFields, setMultipleCustomFields } from '../../../lib/omnichannel/custom-fields';\nimport type { ExtractRoutesFromAPI } from '../../ApiClass';\nimport { findLivechatCustomFields, findCustomFieldById } from './lib/customFields';\nimport { findGuest } from './lib/livechat';\nimport { getPaginationItems } from '../../lib/getPaginationItems';\n\nAPI.v1.addRoute(\n\t'livechat/custom.field',\n\t{ validateParams: isPOSTLivechatCustomFieldParams },\n\t{\n\t\tasync post() {\n\t\t\tconst { token, key, value, overwrite } = this.bodyParams;\n\t\t\tconst guest = await findGuest(token);\n\t\t\tif (!guest) {\n\t\t\t\tthrow new Error('invalid-token');\n\t\t\t}\n\n\t\t\tawait setCustomFields({ token, key, value, overwrite });\n\n\t\t\treturn API.v1.success({ field: { key, value, overwrite } });\n\t\t},\n\t},\n);\n\nAPI.v1.addRoute(\n\t'livechat/custom.fields',\n\t{ validateParams: isPOSTLivechatCustomFieldsParams },\n\t{\n\t\tasync post() {\n\t\t\tconst { token } = this.bodyParams;\n\t\t\tconst visitor = await findGuest(token);\n\t\t\tif (!visitor) {\n\t\t\t\tthrow new Error('invalid-token');","sourceCodeStart":12,"sourceCodeEnd":48,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/f9d3ec372bb580fa8d036f94cf03925a478ef768/apps/meteor/server/api/v1/omnichannel/customField.ts#L12-L48","documentation":"Thrown by POST /api/v1/livechat/custom.field when findGuest(token) returns null. The endpoint accepts a visitor token in the body and looks up the corresponding livechat guest via LivechatVisitors.getVisitorByToken. If no visitor matches, the token is invalid.","triggerScenarios":"Posting to custom.field with a visitor token that does not exist in the LivechatVisitors collection — the token was never issued by this server, was for a different instance, or the visitor record was purged.","commonSituations":"Stale token from a prior server instance; visitor record deleted by retention cleanup; token typo; token from a different environment (test vs production).","solutions":["Verify the token is correct and was issued by this server instance.","Register a new visitor via POST /api/v1/livechat/visitor to obtain a valid token.","Check that the visitor hasn't been purged by retention policies."],"exampleFix":"// before: posting with an unknown token\nPOST /api/v1/livechat/custom.field\n{ \"token\": \"bad-token\", \"key\": \"company\", \"value\": \"Acme\" }\n// after: register visitor first, then set custom field\nPOST /api/v1/livechat/visitor { \"visitor\": { \"token\": \"valid-token-123\" } }\nPOST /api/v1/livechat/custom.field { \"token\": \"valid-token-123\", \"key\": \"company\", \"value\": \"Acme\" }","handlingStrategy":"validation","validationCode":"// Verify the visitor token is valid before setting a custom field\nasync function ensureValidVisitor(baseUrl, token) {\n  const res = await fetch(`${baseUrl}/api/v1/livechat/visitor/${token}`);\n  if (!res.ok) {\n    // Register a new visitor\n    const regRes = await fetch(`${baseUrl}/api/v1/livechat/visitor`, {\n      method: 'POST',\n      headers: { 'Content-Type': 'application/json' },\n      body: JSON.stringify({ visitor: { token } })\n    });\n    return regRes.ok;\n  }\n  return true;\n}","typeGuard":"function isValidVisitorToken(token: unknown): token is string {\n  return typeof token === 'string' && token.trim().length > 0;\n}","tryCatchPattern":"try {\n  await setCustomField({ token, key, value, overwrite });\n} catch (e) {\n  if (e.message === 'invalid-token') {\n    // Re-register the visitor and retry\n    await registerVisitor(token);\n    return setCustomField({ token, key, value, overwrite });\n  }\n  throw e;\n}","preventionTips":["Register the visitor via POST /api/v1/livechat/visitor before using the token in custom field endpoints.","Store visitor tokens securely after registration.","Handle invalid-token errors by re-registering the visitor."],"tags":["omnichannel","livechat","token","visitor","custom-fields"],"backgroundTag":null,"analyzedSha":"f9d3ec372bb580fa8d036f94cf03925a478ef768","analyzedAt":"2026-08-12T19:07:17.372Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}