{"record":{"id":"2e25bb19609372b3","repo":"actualbudget/actual","slug":"invalid-coordinates-latitude-must-be-between-90","errorCode":null,"errorMessage":"Invalid coordinates: latitude must be between -90 and 90, longitude must be between -180 and 180","messagePattern":"Invalid coordinates: latitude must be between -90 and 90, longitude must be between -180 and 180","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/loot-core/src/server/payees/app.ts","lineNumber":167,"sourceCode":"  payeeId,\n  latitude,\n  longitude,\n}: {\n  payeeId: PayeeEntity['id'];\n  latitude: number;\n  longitude: number;\n}): Promise<PayeeLocationEntity['id']> {\n  const created_at = Date.now();\n\n  if (\n    !Number.isFinite(latitude) ||\n    !Number.isFinite(longitude) ||\n    latitude < -90 ||\n    latitude > 90 ||\n    longitude < -180 ||\n    longitude > 180\n  ) {\n    throw new Error(\n      'Invalid coordinates: latitude must be between -90 and 90, longitude must be between -180 and 180',\n    );\n  }\n\n  return await db.insertWithUUID('payee_locations', {\n    payee_id: payeeId,\n    latitude,\n    longitude,\n    created_at,\n  });\n}\n\nasync function getPayeeLocations({\n  payeeId,\n}: {\n  payeeId?: PayeeEntity['id'];\n} = {}): Promise<PayeeLocationEntity[]> {\n  let query = 'SELECT * FROM payee_locations WHERE tombstone IS NOT 1';","sourceCodeStart":149,"sourceCodeEnd":185,"githubUrl":"https://github.com/actualbudget/actual/blob/d4334cb6e6123f4d3bcea1ad6166608884c7e658/packages/loot-core/src/server/payees/app.ts#L149-L185","documentation":"Generic Error thrown by createPayeeLocation when latitude/longitude are non-finite or outside the valid geographic ranges (lat ±90, lon ±180). Prevents storing physically impossible coordinates for payee locations.","triggerScenarios":"Calling createPayeeLocation with latitude outside [-90,90], longitude outside [-180,180], NaN, Infinity, or non-numeric values that pass as NaN/Infinity.","commonSituations":"Geocoding APIs returning null/NaN, latitude/longitude swapped or in degrees-vs-radians confusion, string inputs not coerced to numbers, importing data with empty coordinate columns.","solutions":["Validate latitude is a finite number in [-90,90] and longitude in [-180,180] before calling","Check that lat/lon arguments are not swapped","Coerce string coordinates with Number() and reject NaN before calling","Fix upstream geocoding to skip records with missing coordinates"],"exampleFix":"// before\nawait app.createPayeeLocation(payeeId, '37.77', -122.4); // string lat\n// after\nconst lat = Number('37.77');\nawait app.createPayeeLocation(payeeId, lat, -122.4);","handlingStrategy":"validation","validationCode":"function isValidCoords(lat, lon) {\n  return Number.isFinite(lat) && Number.isFinite(lon) &&\n    lat >= -90 && lat <= 90 && lon >= -180 && lon <= 180;\n}\nif (!isValidCoords(lat, lon)) return;","typeGuard":null,"tryCatchPattern":"try {\n  await app.createPayeeLocation(payeeId, lat, lon);\n} catch (e) {\n  console.warn(`Skipping payee location: ${e.message}`);\n}","preventionTips":["Validate coordinates at the source and skip unknowns","Keep lat/lon order consistent","Coerce and check numeric strings before calling","Reuse one range-check utility everywhere"],"tags":["validation","coordinates","payees"],"backgroundTag":"invalid-coordinate-range","analyzedSha":"d4334cb6e6123f4d3bcea1ad6166608884c7e658","analyzedAt":"2026-08-29T01:02:11.213Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}