medusajs/medusa · error · MedusaError

invalid_data

invalid_data

Error message

Payment collection has not been initiated for cart

What it means

updateStoreCreditAccounts in the loyalty store-credit service validates each account payload against a whitelist of updatable fields. As written, the check `if (whitelistedFields.includes(key)) throw` fires when a key IS in the whitelist — the condition appears inverted versus the message's intent, so supplying `id` or `metadata` throws 'Field ... is not allowed to be updated', and non-whitelisted fields pass through.

Source

Thrown at packages/core/core-flows/src/cart/steps/validate-cart-payments.ts:53

 *   cart
 * })
 */
export const validateCartPaymentsStep = createStep(
  validateCartPaymentsStepId,
  async (data: ValidateCartPaymentsStepInput) => {
    const {
      cart: { payment_collection: paymentCollection, total, credit_line_total },
    } = data

    const canSkipPayment =
      MathBN.convert(credit_line_total).gte(0) && MathBN.convert(total).lte(0)

    if (canSkipPayment) {
      return new StepResponse([])
    }

    if (!isPresent(paymentCollection)) {
      throw new MedusaError(
        MedusaError.Types.INVALID_DATA,
        `Payment collection has not been initiated for cart`
      )
    }

    // We check if any of these payment sessions are present in the cart
    // If not, we throw an error for the consumer to provide a processable payment session
    const processablePaymentStatuses = [
      PaymentSessionStatus.PENDING,
      PaymentSessionStatus.REQUIRES_MORE,
      PaymentSessionStatus.AUTHORIZED, // E.g. payment was authorized, but the cart was not completed
      PaymentSessionStatus.CAPTURED, // E.g. payment was captured, but the cart was not completed
      PaymentSessionStatus.PENDING_AUTHORIZATION, // E.g. async payment method, authorization is deferred
    ]

    const paymentsToProcess = paymentCollection.payment_sessions?.filter((ps) =>
      processablePaymentStatuses.includes(ps.status as PaymentSessionStatus)
    )

View on GitHub (pinned to 5e06e544a2)

Solutions

  1. Fix the guard in the plugin source: throw only when !whitelistedFields.includes(key), and require `id` rather than blacklist it
  2. If you cannot patch the plugin, avoid this method and update via a custom service/query until fixed
  3. Report/patch upstream in packages/plugins/loyalty

Example fix

// before
const whitelistedFields = ["id", "metadata"]
Object.keys(account).forEach((key) => { if (whitelistedFields.includes(key)) throw new Error(`Field ${key} is not allowed to be updated`) })
// after
const whitelistedFields = ["id", "metadata"]
for (const key of Object.keys(account)) { if (key !== "id" && !whitelistedFields.includes(key)) throw new Error(`Field ${key} is not allowed to be updated`) }
Defensive patterns

Strategy: validation

Validate before calling

const allowed = new Set(['metadata'])
const bad = Object.keys(payload).filter(k => k !== 'id' && !allowed.has(k))
if (bad.length) throw new Error(`Fields not allowed: ${bad.join(', ')}`)
// only call the (patched) service when payload is clean

Type guard

const isCleanUpdate = (o: Record<string, unknown>) => Object.keys(o).every(k => k === 'id' || k === 'metadata')

Try / catch

catch (e) { if (e.message.includes('not allowed to be updated')) return badRequest(e.message); throw e }

Prevention

When it happens

Trigger: Calling updateStoreCreditAccounts with any object that includes an `id` or `metadata` key — which is practically every update payload, since `id` is normally required to target the record.

Common situations: Any caller following the standard Medusa update pattern { id, ...changes } hits this immediately; it effectively makes the method unusable until fixed.

Related errors


AI-assisted analysis of medusajs/medusa@5e06e544a2 (2026-08-27). Data as JSON: /api/errors/4533c4ae6230b065. Report an issue: GitHub.