{"id":"656ee627c2ff98e6","repo":"mongodb/node-mongodb-native","slug":"cannot-have-undefined-values-in-key-value-pairs","errorCode":null,"errorMessage":"Cannot have undefined values in key value pairs","messagePattern":"Cannot have undefined values in key value pairs","errorType":"exception","errorClass":"MongoParseError","httpStatus":null,"severity":"error","filePath":"src/connection_string.ts","lineNumber":212,"sourceCode":"}\n\nfunction getUIntFromOptions(name: string, value: unknown): number {\n  const parsedValue = getIntFromOptions(name, value);\n  if (parsedValue < 0) {\n    throw new MongoParseError(`${name} can only be a positive int value, got: ${value}`);\n  }\n  return parsedValue;\n}\n\nfunction* entriesFromString(value: string): Generator<[string, string]> {\n  if (value === '') {\n    return;\n  }\n  const keyValuePairs = value.split(',');\n  for (const keyValue of keyValuePairs) {\n    const [key, value] = keyValue.split(/:(.*)/);\n    if (value == null) {\n      throw new MongoParseError('Cannot have undefined values in key value pairs');\n    }\n\n    yield [key, value];\n  }\n}\n\nclass CaseInsensitiveMap<Value = any> extends Map<string, Value> {\n  constructor(entries: Array<[string, any]> = []) {\n    super(entries.map(([k, v]) => [k.toLowerCase(), v]));\n  }\n  override has(k: string) {\n    return super.has(k.toLowerCase());\n  }\n  override get(k: string) {\n    return super.get(k.toLowerCase());\n  }\n  override set(k: string, v: any) {\n    return super.set(k.toLowerCase(), v);","sourceCodeStart":194,"sourceCodeEnd":230,"githubUrl":"https://github.com/mongodb/node-mongodb-native/blob/3366c21a6311e02f1be91da982f9b93d3cce99a0/src/connection_string.ts#L194-L230","documentation":"Thrown by entriesFromString() when parsing a comma-separated key:value option string and a segment lacks the value after the colon. Used for options parsed as maps such as readPreferenceTags and authMechanismProperties. Splitting 'key:value' on the first ':' yields an undefined value when the segment is 'key' with no colon or ends with a colon. It is a MongoParseError.","triggerScenarios":"URI like ?readPreferenceTags=region:us-east,zone or ?authMechanismProperties=AWS_SESSION_TOKEN: (trailing colon); a tag without a value: ?readPreferenceTags=,; malformed comma-separated entries with stray commas.","commonSituations":"Building readPreferenceTags dynamically and emitting a trailing comma; templating authMechanismProperties with an unset env var producing 'KEY:'; copy-paste from docs that showed a placeholder; concatenating tags with a leading/trailing comma.","solutions":["Ensure every tag/mproperty segment is 'key:value' with both parts non-empty.","Filter empty segments before joining: tags.filter(t => t).join(',').","Validate the built string with a regex like /^[^,]+:[^,]+(,[^,]+:[^,]+)*$/ before passing.","Avoid trailing/leading commas and trailing colons in templated values."],"exampleFix":"// before\nconst tags = [`region:${r}`, zone ? `zone:${zone}` : ''].filter(Boolean).join(',');\n// trailing segment 'zone:' if zone present without value\n// after\nconst tags = [{ region: r }, zone ? { zone } : null]\n  .filter(Boolean)\n  .map(Object.entries)\n  .map(([k, v]) => `${k}:${v}`)\n  .join(',');\nnew MongoClient(uri, { readPreferenceTags: tags ? [tags] : undefined });","handlingStrategy":"validation","validationCode":"function buildTagString(entries: Record<string, string>[]): string {\n  const valid = entries\n    .flatMap(Object.entries)\n    .filter(([k, v]) => k && v)\n    .map(([k, v]) => `${k}:${v}`);\n  if (!valid.length) return '';\n  if (!/^[^,]+:[^,]+(,[^,]+:[^,]+)*$/.test(valid.join(','))) {\n    throw new Error('Malformed key:value tag string');\n  }\n  return valid.join(',');\n}","typeGuard":"const isKeyValueSegments = (s: string): boolean =>\n  s.split(',').every(seg => /^[^:]+:[^:]+$/.test(seg));","tryCatchPattern":"try {\n  await client.connect();\n} catch (e) {\n  if (e instanceof MongoParseError && /undefined values in key value pairs/.test(e.message)) {\n    throw new Error('A readPreferenceTags/authMechanismProperties segment is missing a value');\n  }\n  throw e;\n}","preventionTips":["Filter empty segments before joining tag strings.","Validate the regex /^[^,]+:[^,]+(,[^,]+:[^,]+)*$/ before passing.","Avoid trailing commas and trailing colons when templating."],"tags":["connection-string","parsing","config","read-preference"],"analyzedSha":"3366c21a6311e02f1be91da982f9b93d3cce99a0","analyzedAt":"2026-08-04T13:40:15.335Z","schemaVersion":2}