Repository: medusajs/medusa
File: packages/modules/product/src/services/product-module-service.ts (TypeScript)

Code before:
    if (data.some((option) => !option.id)) {
      throw new MedusaError(
        MedusaError.Types.INVALID_DATA,
        "Tried to update options without specifying an ID"
      )
    }

    const dbOptions = await this.productOptionService_.list(
      { id: data.map(({ id }) => id) },
      { relations: ["values"] },
      sharedContext
    )

    if (dbOptions.length !== data.length) {
      throw new MedusaError(
        MedusaError.Types.INVALID_DATA,
        `Cannot update non-existing options with ids: ${arrayDifference(
          data.map(({ id }) => id),
          dbOptions.map(({ id }) => id)
        ).join(", ")}`
      )
    }

    // Check if any option values are being removed and if they're associated with products
    for (const opt of data) {
      if (opt.values !== undefined) {
        const dbOption = dbOptions.find(({ id }) => id === opt.id)
        if (dbOption) {
          const newValues = new Set<string>(
            opt.values.map((v) => {
              if (isString(v)) {
                return v
              }
              return (v as any).value
            })
          )
          const removedValueIds: string[] = []

          for (const existingValue of dbOption.values || []) {
            if (!newValues.has(existingValue.value)) {
              removedValueIds.push(existingValue.id)
            }
          }

          if (removedValueIds.length > 0) {
            const productProductOptionValues =
              await this.productProductOptionValueService_.list(
                {
                  product_option_value_id: removedValueIds,
                },
                {

Review comment (suggestion):
```suggestion
      if (!isDefined(opt.values)) {
         continue
      }
```

Code after:
  protected async updateOptions_(
    data: UpdateProductOptionInput[],
    @MedusaContext() sharedContext: Context = {}
  ): Promise<InferEntityType<typeof ProductOption>[]> {
    // Validation step
    if (data.some((option) => !option.id)) {
      throw new MedusaError(
        MedusaError.Types.INVALID_DATA,
        "Tried to update options without specifying an ID"
      )
    }

    const dbOptions = await this.productOptionService_.list(
      { id: data.map(({ id }) => id) },
      { relations: ["values"] },
      sharedContext
    )

    if (dbOptions.length !== data.length) {
      throw new MedusaError(
        MedusaError.Types.INVALID_DATA,
        `Cannot update non-existing options with ids: ${arrayDifference(
          data.map(({ id }) => id),
          dbOptions.map(({ id }) => id)
        ).join(", ")}`
      )
    }

    const dbOptionsMap = new Map<string, InferEntityType<typeof ProductOption>>(
      dbOptions.map((option) => [option.id, option])
    )

    // Check if any option values are being removed and if they're associated with products
    const removedValueIds = new Set<string>()
    for (const opt of data) {
      if (!isDefined(opt.values)) {
        continue
      }

      const dbOption = dbOptionsMap.get(opt.id)

      if (!dbOption) {
        continue
      }

      const newValues = new Set<string>(
        opt.values.map((v) => {
          if (isString(v)) {
            return v
          }
          return (v as any).value