{"record":{"id":"76e446e268c8c25a","repo":"NousResearch/hermes-agent","slug":"latitude-longitude-out-of-range","errorCode":null,"errorMessage":"latitude/longitude out of range","messagePattern":"latitude/longitude out of range","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"scripts/whatsapp-bridge/bridge_helpers.js","lineNumber":180,"sourceCode":"  const options = {};\n  const quoted = messageStore?.get(replyTo);\n  if (quoted?.key && quoted?.message) {\n    // Baileys expects quoted messages as sendMessage options, not inside the\n    // message content payload. Keeping this split avoids silently sending a\n    // literal/ignored `quoted` field instead of a native WhatsApp reply.\n    options.quoted = quoted;\n  }\n  return { content, options };\n}\n\nexport function buildLocationPayload({ latitude, longitude, name, address } = {}) {\n  const lat = Number(latitude);\n  const lon = Number(longitude);\n  if (!Number.isFinite(lat) || !Number.isFinite(lon)) {\n    throw new Error('latitude and longitude must be numbers');\n  }\n  if (lat < -90 || lat > 90 || lon < -180 || lon > 180) {\n    throw new Error('latitude/longitude out of range');\n  }\n\n  const location = {\n    degreesLatitude: lat,\n    degreesLongitude: lon,\n  };\n  if (name) location.name = String(name);\n  if (address) location.address = String(address);\n  return { location };\n}\n\nfunction textFromQuotedMessage(quotedMessage) {\n  if (!quotedMessage) return '';\n  if (quotedMessage.conversation) return quotedMessage.conversation;\n  if (quotedMessage.extendedTextMessage?.text) return quotedMessage.extendedTextMessage.text;\n  if (quotedMessage.imageMessage?.caption) return quotedMessage.imageMessage.caption;\n  if (quotedMessage.videoMessage?.caption) return quotedMessage.videoMessage.caption;\n  if (quotedMessage.documentMessage?.caption) return quotedMessage.documentMessage.caption;","sourceCodeStart":162,"sourceCodeEnd":198,"githubUrl":"https://github.com/NousResearch/hermes-agent/blob/c896c09c42910c584c4c7d2325b58c14713ea42c/scripts/whatsapp-bridge/bridge_helpers.js#L162-L198","documentation":"Thrown by buildLocationPayload when the numeric latitude/longitude pass the finite check but fall outside geographic bounds: latitude outside [-90, 90] or longitude outside [-180, 180]. This catches swapped lat/lon, sign errors, and garbage-but-finite numbers before they reach Baileys/WhatsApp.","triggerScenarios":"Passing longitude as latitude (e.g. lat: -122.4, lon: 37.7 for San Francisco), out-of-range values from a miscalculated source, or strings like '999' that coerce to finite numbers.","commonSituations":"Lat/lon argument order swapped in a tool call or LLM-generated payload; degrees/minutes strings partially parsed into wrong magnitudes.","solutions":["Check argument order — latitude comes first and must be within ±90; longitude within ±180.","Validate ranges at the caller/tool-schema level (minimum/maximum in JSON schema) before invoking the bridge.","If coordinates come from an external API, verify units are decimal degrees, not DMS or radians."],"exampleFix":"// before\nbuildLocationPayload({ latitude: -122.4194, longitude: 37.7749 }) // swapped\n\n// after\nbuildLocationPayload({ latitude: 37.7749, longitude: -122.4194 })","handlingStrategy":"validation","validationCode":"function inRange(lat: unknown, lon: unknown): boolean {\n  const a = Number(lat), b = Number(lon)\n  return a >= -90 && a <= 90 && b >= -180 && b <= 180\n}","typeGuard":"function isGeographicPair(p: { latitude: number; longitude: number }): boolean {\n  return Math.abs(p.latitude) <= 90 && Math.abs(p.longitude) <= 180\n}","tryCatchPattern":"try {\n  buildLocationPayload(args)\n} catch (e) {\n  if (e instanceof Error && e.message === 'latitude/longitude out of range')\n    reply('Check the coordinate order and values (lat ±90, lon ±180).')\n  else throw e\n}","preventionTips":["Fix argument order at the boundary — latitude first, bounded by ±90.","Add JSON-schema minimum/maximum bounds for lat/lon in tool definitions.","Sanity-check |lat| <= 90 before invoking the bridge; the common bug is swapped args."],"tags":["whatsapp","bridge","location","validation","range"],"backgroundTag":null,"analyzedSha":"c896c09c42910c584c4c7d2325b58c14713ea42c","analyzedAt":"2026-08-14T17:18:01.089Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}