{"record":{"id":"1b3385983a313a0f","repo":"medusajs/medusa","slug":"missing-required-property-prop-for-geo-zone-typ","errorCode":null,"errorMessage":"Missing required property ${prop} for geo zone type ${geoZone.type}","messagePattern":"Missing required property (.+?) for geo zone type (.+?)","errorType":"validation","errorClass":"MedusaError","httpStatus":400,"severity":"error","filePath":"packages/modules/fulfillment/src/services/fulfillment-module-service.ts","lineNumber":2169,"sourceCode":"  ) {\n    const requirePropForType = {\n      country: [\"country_code\"],\n      province: [\"country_code\", \"province_code\"],\n      city: [\"country_code\", \"province_code\", \"city\"],\n      zip: [\"country_code\", \"province_code\", \"city\", \"postal_expression\"],\n    }\n\n    for (const geoZone of geoZones) {\n      if (!requirePropForType[geoZone.type]) {\n        throw new MedusaError(\n          MedusaError.Types.INVALID_DATA,\n          `Invalid geo zone type: ${geoZone.type}`\n        )\n      }\n\n      for (const prop of requirePropForType[geoZone.type]) {\n        if (!geoZone[prop]) {\n          throw new MedusaError(\n            MedusaError.Types.INVALID_DATA,\n            `Missing required property ${prop} for geo zone type ${geoZone.type}`\n          )\n        }\n      }\n    }\n  }\n\n  protected static normalizeListShippingOptionsForContextParams(\n    filters: FulfillmentTypes.FilterableShippingOptionForContextProps,\n    config: FindConfig<ShippingOptionDTO> = {}\n  ) {\n    let {\n      fulfillment_set_id,\n      fulfillment_set_type,\n      address,\n      context,\n      ...where","sourceCodeStart":2151,"sourceCodeEnd":2187,"githubUrl":"https://github.com/medusajs/medusa/blob/5e06e544a296b9033f20f71f11c559f81a0e5739/packages/modules/fulfillment/src/services/fulfillment-module-service.ts#L2151-L2187","documentation":"Each geo zone type requires an escalating set of properties: country needs country_code; province adds province_code; city adds city; zip adds postal_expression. If any required property for the declared type is missing/falsy, this INVALID_DATA error is thrown.","triggerScenarios":"Creating a zone with type 'zip' but only a country_code, or type 'city' without province_code — commonly from partially-filled forms or sparse CSV imports.","commonSituations":"Assuming only some fields are required; frontend not enforcing conditional required fields per zone type.","solutions":["Provide all required props for the type: country→country_code; province→+province_code; city→+city; zip→+postal_expression","Downgrade the type if you only have partial data (e.g. use 'country' when only country_code is known)","Add conditional form validation based on selected type"],"exampleFix":"// before\nawait service.createGeoZones([{ type: 'zip', country_code: 'us', province_code: 'ca' }])\n// after\nawait service.createGeoZones([{ type: 'zip', country_code: 'us', province_code: 'ca', city: 'LA', postal_expression: '90210' }])","handlingStrategy":"validation","validationCode":"const REQUIRED: Record<string, string[]> = { country: ['country_code'], province: ['country_code','province_code'], city: ['country_code','province_code','city'], zip: ['country_code','province_code','city','postal_expression'] }\nconst missing = (REQUIRED[zone.type] ?? []).filter((p) => !zone[p])\nif (missing.length) throw new Error(`Missing: ${missing.join(', ')}`)","typeGuard":"const hasRequiredGeoZoneProps = (z: any): boolean => (REQUIRED[z.type] ?? []).every((p) => !!z[p])","tryCatchPattern":null,"preventionTips":["Enforce conditional required fields in the UI based on selected type","Fall back to a broader type when only partial address data exists"],"tags":["fulfillment","geo-zone","required-field","validation"],"backgroundTag":"missing-required-field","analyzedSha":"5e06e544a296b9033f20f71f11c559f81a0e5739","analyzedAt":"2026-08-27T07:24:39.599Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}