{"record":{"id":"763ee4176f8c75b2","repo":"RocketChat/Rocket.Chat","slug":"auth-option-should-be-of-the-form-username-passwo-763ee4","errorCode":null,"errorMessage":"auth option should be of the form \"username:password\"","messagePattern":"auth option should be of the form \"username:password\"","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"apps/meteor/server/lib/integrations/lib/triggerHandler.ts","lineNumber":596,"sourceCode":"\t\t\t\tawait updateHistory({ historyId, step: 'after-prepare-send-message-failed', finished: true });\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tawait updateHistory({\n\t\t\t\thistoryId,\n\t\t\t\tstep: 'after-prepare-send-message',\n\t\t\t\tprepareSentMessage: prepareMessage,\n\t\t\t});\n\t\t}\n\n\t\tif (!opts.url || !opts.method) {\n\t\t\tawait updateHistory({ historyId, step: 'after-prepare-no-url_or_method', finished: true });\n\t\t\treturn;\n\t\t}\n\n\t\t// based on HTTP.call implementation\n\t\tif (opts.auth) {\n\t\t\tif (opts.auth.indexOf(':') < 0) {\n\t\t\t\tthrow new Error('auth option should be of the form \"username:password\"');\n\t\t\t}\n\n\t\t\tconst base64 = Buffer.from(opts.auth, 'ascii').toString('base64');\n\t\t\topts.headers.Authorization = `Basic ${base64}`;\n\t\t}\n\n\t\tawait updateHistory({\n\t\t\thistoryId,\n\t\t\tstep: 'pre-http-call',\n\t\t\turl: opts.url,\n\t\t\thttpCallData: opts.data,\n\t\t});\n\n\t\tif (opts.data) {\n\t\t\topts.headers['Content-Type'] = 'application/json';\n\t\t}\n\n\t\tfetch(","sourceCodeStart":578,"sourceCodeEnd":614,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0/apps/meteor/server/lib/integrations/lib/triggerHandler.ts#L578-L614","documentation":"Thrown by the outgoing-webhook trigger handler in executeTriggerUrl after an integration's 'Prepare Outgoing Requests' script returns an opts object whose `auth` string contains no ':' character. Mirroring Meteor's HTTP.call behavior, the server converts opts.auth into a Basic Authorization header (`Basic base64(user:pass)`), which is only possible when the value separates username and password with a colon. The error aborts the webhook execution before any HTTP request is made.","triggerScenarios":"An outgoing webhook integration runs a Prepare Outgoing Requests script that returns `{ url, method: 'POST', auth: token }` where token is a bearer/API token (no ':'), or a username without password, or an undefined variable interpolated as e.g. 'undefined'. executeTriggerUrl calls scriptEngine.prepareOutgoingRequest, gets opts.auth without a colon, and throws at triggerHandler.ts:596 before the HTTP call and before history step 'pre-http-call'.","commonSituations":"Script authors porting curl examples that use `Authorization: Bearer <token>` and assuming the `auth` option accepts tokens; secrets with special characters handled incorrectly; copy-pasted scripts from older Rocket.Chat docs; CI notifications where the password was left empty (`user:` works, but `user` alone does not).","solutions":["In the integration's Prepare Outgoing Requests script, return auth as a single 'username:password' string, e.g. `return { url, method: 'POST', auth: `${user}:${password}` };`","For token/Bearer schemes do not use `auth` at all; set the header directly: `headers: { Authorization: `Bearer ${token}` }`","If user or password contain reserved characters, wrap each part with encodeURIComponent while keeping exactly one ':' separator","Open Admin -> Integrations -> (integration) -> History and inspect the last steps (after-maybe-ran-prepare) to see exactly what the script returned before fixing it"],"exampleFix":"// before (Prepare Outgoing Requests script)\nreturn { url, method: 'POST', auth: accessToken };\n\n// after — basic auth as 'username:password'\nreturn { url, method: 'POST', auth: `${user}:${password}` };\n\n// or, for token auth, set the header directly and skip `auth`\nreturn { url, method: 'POST', headers: { Authorization: `Bearer ${accessToken}` } };","handlingStrategy":"validation","validationCode":"// inside the integration's Prepare Outgoing Requests script\nconst basic = `${encodeURIComponent(user)}:${encodeURIComponent(password)}`;\nif (!basic.includes(':')) {\n  throw new TypeError('auth must be of the form \"username:password\"');\n}\nreturn { url, method: 'POST', auth: basic };","typeGuard":"const hasUsableAuth = (opts: { auth?: string }): boolean =>\n  opts.auth === undefined || (typeof opts.auth === 'string' && opts.auth.includes(':'));","tryCatchPattern":null,"preventionTips":["Never put raw tokens in opts.auth; use opts.headers.Authorization for Bearer schemes","Build the auth string in one place (`${user}:${password}`) so the separator cannot be lost","Test the Prepare script with a dry-run message and check integration History before relying on the webhook"],"tags":["integrations","outgoing-webhook","basic-auth","http","script"],"backgroundTag":"basic-auth-credentials-format","analyzedSha":"b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0","analyzedAt":"2026-08-18T15:26:39.429Z","schemaVersion":2},"datasetVersion":"2026-08-21T13:17:26.733Z"}