{"record":{"id":"cc342bc32a0ba9af","repo":"Freika/dawarich","slug":"latitude","errorCode":null,"errorMessage":"latitude","messagePattern":"latitude","errorType":"validation","errorClass":"ActionController::ParameterMissing","httpStatus":422,"severity":"warning","filePath":"app/controllers/api/v1/visits/select_place_controller.rb","lineNumber":24,"sourceCode":"    place = Visits::SelectPlace.new(user: current_api_user, visit: visit, photon: photon_params).call\n    render json: serialize_place(place), status: :created\n  rescue ActiveRecord::RecordNotFound\n    render json: { error: I18n.t('controllers.api.v1.visits.select_place.visit_not_found') }, status: :not_found\n  rescue ActiveRecord::RecordInvalid, ActionController::ParameterMissing => e\n    render json: { error: e.message }, status: :unprocessable_entity\n  end\n\n  private\n\n  def photon_params\n    params.require(:photon).permit(\n      :name, :latitude, :longitude,\n      :osm_id, :osm_type, :osm_key, :osm_value,\n      :city, :country, :street, :housenumber, :postcode,\n      geodata: {}\n    ).tap do |p|\n      raise ActionController::ParameterMissing, :name      if p[:name].blank?\n      raise ActionController::ParameterMissing, :latitude  if p[:latitude].blank?\n      raise ActionController::ParameterMissing, :longitude if p[:longitude].blank?\n\n      lat = p[:latitude].to_f\n      lon = p[:longitude].to_f\n      raise ActionController::ParameterMissing, :latitude  unless lat.between?(-90, 90)\n      raise ActionController::ParameterMissing, :longitude unless lon.between?(-180, 180)\n    end\n  end\n\n  def serialize_place(place)\n    tags = place.tags.to_a\n    first_tag = tags.first\n\n    {\n      id: place.id,\n      name: place.name,\n      latitude: place.lat,\n      longitude: place.lon,","sourceCodeStart":6,"sourceCodeEnd":42,"githubUrl":"https://github.com/Freika/dawarich/blob/97fad417c5a11b0eb11157890635e015723a2e97/app/controllers/api/v1/visits/select_place_controller.rb#L6-L42","documentation":"Same strong-parameters gate as the name check: photon[latitude] must be present and non-blank or ActionController::ParameterMissing with message 'latitude' is raised, rendered by the controller rescue as json {error: 'latitude'} with 422. This is the blank check only - range validation of the parsed float happens separately at line 29.","triggerScenarios":"POST /api/v1/visits/select_place where the photon payload omits latitude, sends it as '' or null, or the client sends lat/lon under different key names (e.g. lat instead of latitude) so the permit filter drops them.","commonSituations":"Client code migrating from a lat/lon naming convention to latitude/longitude, geolocation permission denied so the browser returns undefined coords, copy-pasting place JSON from another API that uses different field names.","solutions":["Send photon[latitude] as a non-empty numeric string or float","Rename any lat/lon fields in the client payload to latitude/longitude before submitting","Guard in the UI: disable the select-place button until a coordinate is picked from the map/search result","Treat the {error: 'latitude'} 422 body as 'Latitude is required' when surfacing to users"],"exampleFix":"// before\nbody: JSON.stringify({ photon: { name: 'Home', longitude: 13.4 } })\n\n// after\nbody: JSON.stringify({ photon: { name: 'Home', latitude: 52.5, longitude: 13.4 } })","handlingStrategy":"validation","validationCode":"function hasLatitude(p) {\n  return p != null && p.latitude !== undefined && p.latitude !== null && String(p.latitude).trim() !== ''\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use the server's key names (latitude, not lat) in every client payload","Only enable the select-place action after a map pin or search result supplies coordinates","Treat the 422 {error: 'latitude'} body as a field-level validation signal, not a server bug"],"tags":["rails","api","strong-parameters","validation","visits"],"backgroundTag":"missing-required-parameter","analyzedSha":"97fad417c5a11b0eb11157890635e015723a2e97","analyzedAt":"2026-08-21T17:04:17.778Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}