Skip to content

Fix TypeError when cheapest AirPricingSolution is not the first in the list#680

Draft
Copilot wants to merge 2 commits intomasterfrom
copilot/fix-passenger-type-error
Draft

Fix TypeError when cheapest AirPricingSolution is not the first in the list#680
Copilot wants to merge 2 commits intomasterfrom
copilot/fix-passenger-type-error

Conversation

Copy link
Copy Markdown

Copilot AI commented Mar 2, 2026

airPriceRspPassengersPerReservation always read passenger type counts from priceKeys[0] (the first pricing solution), while airPriceRspPricingSolutionXML selected the cheapest solution. When the cheapest solution wasn't first, the AirPricingInfo keys diverged, pricingInfo.find(...) returned undefined, and the subsequent .push() threw a TypeError.

Changes

  • airPriceRspPassengersPerReservation — now selects the cheapest pricing solution using the same TotalPrice.slice(3) comparison already used elsewhere, ensuring it operates on the same solution as airPriceRspPricingSolutionXML:
const cheapestKey = priceKeys.length > 1
  ? priceKeys.reduce((minKey, key) => (
      parseFloat(prices[key].TotalPrice.slice(3)) < parseFloat(prices[minKey].TotalPrice.slice(3))
        ? key : minKey
    ))
  : priceKeys[0];
  • airPriceRspPricingSolutionXML — added a null guard on pricingInfo before calling .push() as defense-in-depth.

  • New test fixture AirPricingSolution.2AirPrice.cheapest-second.xml — cloned from the existing two-solution fixture with prices swapped so the second solution is cheaper.

  • New test case — asserts that the cheapest solution's key and TotalPrice are used, and that BookingTravelerRef entries reference the correct AirPricingInfo.

Original prompt

This section details on the original issue you should resolve

<issue_title>TypeError: Cannot read properties of undefined (reading 'air:PassengerType')</issue_title>
<issue_description>Hi, I’m encountering an error during passenger assignment when parsing AirPricingInfo.

TypeError: Cannot read properties of undefined (reading 'air:PassengerType')
at AirParser.js:384

After debugging, I found the root cause:

The code attempts to map each passenger to a corresponding AirPricingInfo using a reservationKey.

However, in some responses, the generated reservationKey does not match any AirPricingInfo.$.Key.

As a result, pricingInfo becomes undefined.

Then the code tries to execute:

pricingInfo['air:PassengerType'].push(...)

which throws the TypeError.

What I observed

reservationKey sometimes becomes undefined because the matching logic finds no suitable reservation.

pricingInfos.find(info => info.$.Key === reservationKey) then returns undefined.

Some AirPricingInfo objects also do not include the air:PassengerType field initially.

Expected behavior

The parser should safely handle missing reservationKey or missing air:PassengerType fields instead of throwing a TypeError.

Suggested fix

Before writing to pricingInfo['air:PassengerType'], add validation:

if (!pricingInfo) {
// handle missing pricingInfo gracefully
}

if (!Array.isArray(pricingInfo['air:PassengerType'])) {
pricingInfo['air:PassengerType'] = [];
}

Additional notes

This issue happens when multiple pricing solutions exist and the library selects the cheapest one, but that solution’s internal structure does not match the expected PassengerType mapping.

Please let me know if you want sample request/response XML — I can provide them.

Thanks!

XML Request:
<soap:Envelope
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
soap:Header/
soap:Body
<air:AirPriceReq
AuthorizedBy="user" CheckFlightDetails="false" TargetBranch="xxxxx"
TraceId="59cb0657-aa20-446e-a7bd-6c3cc7115532"

  xmlns:air="http://www.travelport.com/schema/air_v54_0"

  xmlns:com="http://www.travelport.com/schema/common_v54_0">
  <com:BillingPointOfSaleInfo OriginApplication="UAPI"
    xmlns:com="http://www.travelport.com/schema/common_v54_0"/>
    <air:AirItinerary>
      <air:AirSegment ArrivalTime="2025-12-04T13:15:00.000-05:00"
                            DepartureTime="2025-12-04T12:10:00.000-04:00"
                            Carrier="AV"
                             ClassOfService="Q"
                            CabinClass="Economy"
                            Origin="CCS"
                            Destination="BOG"
                            ETicketability="Yes"
                            Equipment="320"
                            FlightNumber="143"
                            LinkAvailability="true"
                            PolledAvailabilityOption="Polled avail exists"
                            ProviderCode="1G"
                            Key="0"
                            Group="0"></air:AirSegment>
    </air:AirItinerary>
    <air:AirPricingModifiers InventoryRequestType="DirectAccess"/>
    <com:SearchPassenger Key="P_0" Code="ADT" Age="59"
      xmlns:com="http://www.travelport.com/schema/common_v54_0"/>
      <air:AirPricingCommand>
        <air:AirSegmentPricingModifiers AirSegmentRef="0">
          <air:PermittedBookingCodes>
            <air:BookingCode Code="Q" />
          </air:PermittedBookingCodes>
        </air:AirSegmentPricingModifiers>
      </air:AirPricingCommand>
    </air:AirPriceReq>
  </soap:Body>
</soap:Envelope>

XML Response:
<air:AirPriceRsp xmlns:air="http://www.travelport.com/schema/air_v54_0" xmlns:common_v54_0="http://www.travelport.com/schema/common_v54_0" TraceId="59cb0657-aa20-446e-a7bd-6c3cc7115532" TransactionId="70A38AEC0A0E7C3140AFAC5239C0C3A2" ResponseTime="339">
<common_v54_0:ResponseMessage Code="710401" Type="Warning" ProviderCode="1G"></common_v54_0:ResponseMessage>
air:AirItinerary
<air:AirSegment Key="WAgWupxwnDKAZFccCCAAAA==" Group="0" Carrier="AV" FlightNumber="143" ProviderCode="1G" Origin="CCS" Destination="BOG" DepartureTime="2025-12-04T12:10:00.000-04:00" ArrivalTime="2025-12-04T13:15:00.000-05:00" FlightTime="125" TravelTime="125" Distance="638" ClassOfService="Q" Equipment="320" ChangeOfPlane="false" OptionalServicesIndicator="false" AvailabilitySource="S" LinkAvailability="true" PolledAvailabilityOption="O and D cache or polled status used with different local status" AvailabilityDisplayType="Fare Specific Fare Quote Unbooked">
<air:CodeshareInfo OperatingCarrier="AV">AVIANCA</air:CodeshareInfo>
<air:FlightDetails Key="WAgWu...


🔒 GitHub Advanced Security automatically protects Copilot coding agent pull requests. You can protect all pull requests by enabling Advanced Security for your repositories. Learn more about Advanced Security.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot wasn't able to review any files in this pull request.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

- Fix airPriceRspPassengersPerReservation to select the cheapest pricing
  solution (matching airPriceRspPricingSolutionXML's selection logic)
  instead of always using priceKeys[0]
- Add null-safety guard for pricingInfo being undefined
- Add test fixture where cheapest solution is not the first one
- Add test case verifying correct solution selection and passenger key association

Co-authored-by: Smotrov <7815789+Smotrov@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix TypeError when reading air:PassengerType during passenger assignment Fix TypeError when cheapest AirPricingSolution is not the first in the list Mar 12, 2026
@sonarqubecloud
Copy link
Copy Markdown

Quality Gate Failed Quality Gate failed

Failed conditions
C Reliability Rating on New Code (required ≥ A)

See analysis details on SonarQube Cloud

Catch issues before they fail your Quality Gate with our IDE extension SonarQube for IDE

@Smotrov Smotrov requested a review from dchertousov March 12, 2026 09:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

TypeError: Cannot read properties of undefined (reading 'air:PassengerType')

3 participants