{"id":"509e517563ee3feb","repo":"mongodb/node-mongodb-native","slug":"auth-mechanism-property-allowed-hosts-must-be-an-a","errorCode":null,"errorMessage":"Auth mechanism property ALLOWED_HOSTS must be an array of strings.","messagePattern":"Auth mechanism property ALLOWED_HOSTS must be an array of strings\\.","errorType":"validation","errorClass":"MongoInvalidArgumentError","httpStatus":null,"severity":"error","filePath":"src/cmap/auth/mongo_credentials.ts","lineNumber":240,"sourceCode":"            ','\n          )} is supported for mechanism '${this.mechanism}'.`\n        );\n      }\n\n      if (\n        !this.mechanismProperties.ENVIRONMENT &&\n        !this.mechanismProperties.OIDC_CALLBACK &&\n        !this.mechanismProperties.OIDC_HUMAN_CALLBACK\n      ) {\n        throw new MongoInvalidArgumentError(\n          `Either a ENVIRONMENT, OIDC_CALLBACK, or OIDC_HUMAN_CALLBACK must be specified for mechanism '${this.mechanism}'.`\n        );\n      }\n\n      if (this.mechanismProperties.ALLOWED_HOSTS) {\n        const hosts = this.mechanismProperties.ALLOWED_HOSTS;\n        if (!Array.isArray(hosts)) {\n          throw new MongoInvalidArgumentError(ALLOWED_HOSTS_ERROR);\n        }\n        for (const host of hosts) {\n          if (typeof host !== 'string') {\n            throw new MongoInvalidArgumentError(ALLOWED_HOSTS_ERROR);\n          }\n        }\n      }\n    }\n\n    if (AUTH_MECHS_AUTH_SRC_EXTERNAL.has(this.mechanism)) {\n      if (this.source != null && this.source !== '$external') {\n        // TODO(NODE-3485): Replace this with a MongoAuthValidationError\n        throw new MongoAPIError(\n          `Invalid source '${this.source}' for mechanism '${this.mechanism}' specified.`\n        );\n      }\n    }\n","sourceCodeStart":222,"sourceCodeEnd":258,"githubUrl":"https://github.com/mongodb/node-mongodb-native/blob/3366c21a6311e02f1be91da982f9b93d3cce99a0/src/cmap/auth/mongo_credentials.ts#L222-L258","documentation":"Thrown for MONGODB-OIDC when authMechanismProperties.ALLOWED_HOSTS is provided but is not an array. ALLOWED_HOSTS restricts which MongoDB hostnames the driver will send the OIDC token to (preventing token theft via redirect); it must be an array of strings. This specific branch catches the non-array case (object, string, number, etc.).","triggerScenarios":"In MongoCredentials.validate() when ALLOWED_HOSTS is truthy but Array.isArray(hosts) is false.","commonSituations":"Passing ALLOWED_HOSTS as a comma-separated string in the URI instead of an array (URI parsing usually splits these, but a programmatic options object may not); passing a single hostname string in the options object; misconfigured options spread.","solutions":["Pass ALLOWED_HOSTS as an array: { ALLOWED_HOSTS: ['host.example.com'] }.","In a connection string, use the form authMechanismProperties=ALLOWED_HOSTS:host1,host2 (the parser splits on comma).","If building options programmatically, ensure the field is always an array."],"exampleFix":"// before\nauthMechanismProperties: { ALLOWED_HOSTS: 'cluster.mongodb.net' }\n\n// after\nauthMechanismProperties: { ALLOWED_HOSTS: ['cluster.mongodb.net'] }","handlingStrategy":"type-guard","validationCode":"function normalizeAllowedHosts(v: unknown): string[] {\n  if (v == null) return [];\n  if (!Array.isArray(v)) throw new Error('ALLOWED_HOSTS must be an array of strings');\n  return v as string[];\n}","typeGuard":"function isStringArray(v: unknown): v is string[] {\n  return Array.isArray(v) && v.every(x => typeof x === 'string');\n}","tryCatchPattern":null,"preventionTips":["Pass ALLOWED_HOSTS as an array in programmatic options.","In URIs, use comma-separated values so the parser splits them."],"tags":["auth","oidc","configuration","type-safety"],"analyzedSha":"3366c21a6311e02f1be91da982f9b93d3cce99a0","analyzedAt":"2026-08-04T13:40:15.335Z","schemaVersion":2}