From 3ce405263333d4f82f3ae9100bc7b1b2eafb17e2 Mon Sep 17 00:00:00 2001 From: Aishwarya Date: Mon, 24 Aug 2026 13:48:44 +0530 Subject: [PATCH 1/3] fix: improve asset and reference processing to handle already resolved objects in drupal --- api/src/services/drupal/entries.service.ts | 26 ++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/api/src/services/drupal/entries.service.ts b/api/src/services/drupal/entries.service.ts index 84b4b5587..b550b214d 100644 --- a/api/src/services/drupal/entries.service.ts +++ b/api/src/services/drupal/entries.service.ts @@ -441,11 +441,18 @@ const processFieldByType = ( case 'file': { // File/Asset processing with proper validation and cleanup + // Note: earlier processing (processFieldData) may have already resolved + // the raw target_id into an asset reference object - pass those through + // as-is instead of re-deriving `assets_${value}` from the object. if (fieldMapping.advanced?.multiple) { // Multiple files if (Array.isArray(value)) { const validAssets = value ?.map((assetRef) => { + if (assetRef && typeof assetRef === 'object' && assetRef?.uid) { + return assetRef; // Already resolved + } + const assetKey = `assets_${assetRef}`; const assetReference = assetId?.[assetKey]; @@ -464,6 +471,10 @@ const processFieldByType = ( } } else { // Single file + if (value && typeof value === 'object' && value?.uid) { + return value; // Already resolved + } + const assetKey = `assets_${value}`; const assetReference = assetId?.[assetKey]; @@ -479,16 +490,23 @@ const processFieldByType = ( case 'reference': { // Reference processing + // Note: earlier processing (processFieldData) may have already resolved + // reference ids into reference objects - pass those through as-is. if (fieldMapping.advanced?.multiple) { // Multiple references if (Array.isArray(value)) { - return value?.map( - (refId) => - referenceId?.[`content_type_entries_title_${refId}`] || refId, - ); + return value?.map((refId) => { + if (refId && typeof refId === 'object' && refId?.uid) { + return refId; // Already resolved + } + return referenceId?.[`content_type_entries_title_${refId}`] || refId; + }); } } else { // Single reference + if (value && typeof value === 'object' && value?.uid) { + return [value]; // Already resolved + } return [referenceId?.[`content_type_entries_title_${value}`] || value]; } return value; From 5676adb3da2af5f8baafe5768198a49d7bf47ae1 Mon Sep 17 00:00:00 2001 From: Aishwarya Date: Mon, 24 Aug 2026 15:33:15 +0530 Subject: [PATCH 2/3] fix: handle single-value reference fields without nesting in processFieldByType --- api/src/services/drupal/entries.service.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/api/src/services/drupal/entries.service.ts b/api/src/services/drupal/entries.service.ts index b550b214d..e3b2f1b54 100644 --- a/api/src/services/drupal/entries.service.ts +++ b/api/src/services/drupal/entries.service.ts @@ -504,6 +504,12 @@ const processFieldByType = ( } } else { // Single reference + if (Array.isArray(value)) { + // processFieldData normalizes reference target_ids into an array of + // resolved reference objects even for single-value fields - return + // as-is instead of wrapping again into a nested array [[{uid,...}]]. + return value; + } if (value && typeof value === 'object' && value?.uid) { return [value]; // Already resolved } From a9676643e4c8da66c82446731b95b9c0a2993e70 Mon Sep 17 00:00:00 2001 From: Aishwarya Date: Mon, 24 Aug 2026 18:37:15 +0530 Subject: [PATCH 3/3] fix: normalize asset references in processFieldByType to handle single-value fields correctly --- api/src/services/drupal/entries.service.ts | 31 ++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/api/src/services/drupal/entries.service.ts b/api/src/services/drupal/entries.service.ts index e3b2f1b54..3368226e6 100644 --- a/api/src/services/drupal/entries.service.ts +++ b/api/src/services/drupal/entries.service.ts @@ -469,6 +469,23 @@ const processFieldByType = ( return validAssets?.length > 0 ? validAssets : undefined; // Return undefined if no valid assets } + + // processFieldData resolves asset target_ids to a single reference + // object even for multiple-value fields - normalize into an array + // instead of returning a bare object where Contentstack expects one. + if (value && typeof value === 'object' && value?.uid) { + return [value]; + } + + const assetKey = `assets_${value}`; + const assetReference = assetId?.[assetKey]; + + if (assetReference && typeof assetReference === 'object') { + return [assetReference]; + } + + console.error(`Asset ${assetKey} not found or invalid, removing field`); + return undefined; } else { // Single file if (value && typeof value === 'object' && value?.uid) { @@ -508,7 +525,14 @@ const processFieldByType = ( // processFieldData normalizes reference target_ids into an array of // resolved reference objects even for single-value fields - return // as-is instead of wrapping again into a nested array [[{uid,...}]]. - return value; + // Mirror the `multiple` branch above and resolve any raw (unresolved) + // IDs still present, e.g. from _tid fields built in the ctValue loop. + return value.map((refId) => { + if (refId && typeof refId === 'object' && refId?.uid) { + return refId; // Already resolved + } + return referenceId?.[`content_type_entries_title_${refId}`] || refId; + }); } if (value && typeof value === 'object' && value?.uid) { return [value]; // Already resolved @@ -695,8 +719,11 @@ const processFieldData = async ( const assetReference = assetId?.[assetKey]; if (assetReference && typeof assetReference === 'object') { processedData[dataKey] = assetReference; + } else { + console.error(`Asset ${assetKey} not found or invalid, removing field`); } - // If asset reference is not properly structured, skip the field + } else { + console.error(`Asset ${assetKey} not found or invalid, removing field`); } // If asset not found in assets index, mark field as skipped skippedFields?.add(dataKey);