Skip to content Skip to sidebar

This is the technical support forum for WPML - the multilingual WordPress plugin.

Everyone can read, but only WPML clients can post here. WPML team is replying on the forum 6 days per week, 22 hours per day.

Sun Mon Tue Wed Thu Fri Sat
- 8:00 – 13:00 9:00 – 13:00 9:00 – 13:00 8:00 – 12:00 8:00 – 12:00 -
- 14:00 – 17:00 14:00 – 18:00 14:00 – 18:00 13:00 – 17:00 13:00 – 17:00 -

Supporter timezone: Europe/Zagreb (GMT+01:00)

Tagged: 

This topic contains 4 replies, has 0 voices.

Last updated by Bruno Kos 4 weeks ago.

Assisted by: Bruno Kos.

Author Posts
November 11, 2025 at 3:56 pm

jasonK-12

Background of the issue:
I am trying to use ACF nested Repeater fields with your WPML plugin. The issue can be seen on this page: hidden link. I expected the page to be translated but get a critical error

Symptoms:
I encountered a critical error and a warning indicating that your plugin is trying to convert the child repeater fields array into a string.

Fatal error: Uncaught TypeError: strlen(): Argument #1 ($string) must be of type string, array given in /Users/nathanfarleigh/Local Sites/casa-de-campo-development/app/public/wp-content/plugins/wpml-string-translation/classes/filters/strings-filter/class-wpml-register-string-filter.php:193 Stack trace: #0 /Users/nathanfarleigh/Local Sites/casa-de-campo-development/app/public/wp-content/plugins/wpml-string-translation/classes/filters/strings-filter/class-wpml-register-string-filter.php(170): WPML_Register_String_Filter->save_string(Array, false, 'en', 'gutenberg-1059', '', 'ce56e2b4776ab77...') #1 /Users/nathanfarleigh/Local Sites/casa-de-campo-development/app/public/wp-content/plugins/wpml-string-translation/inc/functions.php(210): WPML_Register_String_Filter->register_string('', 'ce56e2b4776ab77...', Array, false, 'en') #2 /Users/nathanfarleigh/Local Sites/casa-de-campo-development/app/public/wp-content/plugins/wpml-string-translation/inc/package-translation/inc/wpml-package.class.php(314): icl_register_string('gutenberg-1059', 'ce56e2b4776ab77...', Array, false, 'en') #3 /Users/nathanfarleigh/Local Sites/casa-de-campo-development/app/public/wp-content/plugins/wpml-string-translation/inc/package-translation/inc/wpml-package-translation-helper.class.php(556): WPML_Package->get_string_id_from_package('ce56e2b4776ab77...', Array) #4 /Users/nathanfarleigh/Local Sites/casa-de-campo-development/app/public/wp-content/plugins/wpml-string-translation/inc/package-translation/inc/wpml-package-translation-helper.class.php(199): WPML_Package_Helper->get_string_id_from_package(Object(WPML_Package), 'ce56e2b4776ab77...', Array) #5 /Users/nathanfarleigh/Local Sites/casa-de-campo-development/app/public/wp-content/plugins/wpml-string-translation/inc/package-translation/inc/wpml-package-translation-helper.class.php(161): WPML_Package_Helper->register_string_with_wpml(Object(WPML_Package), 'ce56e2b4776ab77...', 'acf-tabs-conten...', 'array', Array) #6 /Users/nathanfarleigh/Local Sites/casa-de-campo-development/app/public/wp-content/plugins/wpml-string-translation/inc/package-translation/inc/wpml-package-translation-helper.class.php(90): WPML_Package_Helper->register_string_for_translation(Array, 'ce56e2b4776ab77...', Object(WPML_Package), 'acf-tabs-conten...', 'array') #7 /Users/nathanfarleigh/Local Sites/casa-de-campo-development/app/public/wp-includes/class-wp-hook.php(324): WPML_Package_Helper->register_string_action(Array, 'ce56e2b4776ab77...', Array, 'acf-tabs-conten...', 'array') #8 /Users/nathanfarleigh/Local Sites/casa-de-campo-development/app/public/wp-includes/class-wp-hook.php(348): WP_Hook->apply_filters('', Array) #9 /Users/nathanfarleigh/Local Sites/casa-de-campo-development/app/public/wp-includes/plugin.php(517): WP_Hook->do_action(Array) #10 /Users/nathanfarleigh/Local Sites/casa-de-campo-development/app/public/wp-content/plugins/sitepress-multilingual-cms/addons/wpml-page-builders/classes/Integrations/Gutenberg/class-wpml-gutenberg-strings-registration.php(141): do_action('wpml_register_s...', Array, 'ce56e2b4776ab77...', Array, 'acf-tabs-conten...', 'array') #11 /Users/nathanfarleigh/Local Sites/casa-de-campo-development/app/public/wp-content/plugins/sitepress-multilingual-cms/addons/wpml-page-builders/classes/Integrations/Gutenberg/class-wpml-gutenberg-strings-registration.php(168): WPML_Gutenberg_Strings_Registration->register_blocks(Array, Array, 1059, Array) #12 /Users/nathanfarleigh/Local Sites/casa-de-campo-development/app/public/wp-content/plugins/sitepress-multilingual-cms/addons/wpml-page-builders/classes/Integrations/Gutenberg/class-wpml-gutenberg-strings-registration.php(63): WPML_Gutenberg_Strings_Registration->register_blocks(Array, Array, 1059) #13 /Users/nathanfarleigh/Local Sites/casa-de-campo-development/app/public/wp-content/plugins/sitepress-multilingual-cms/addons/wpml-page-builders/classes/Integrations/Gutenberg/class-wpml-gutenberg-integration.php(68): WPML_Gutenberg_Strings_Registration->register_strings(Object(WP_Post), Array) #14 /Users/nathanfarleigh/Local Sites/casa-de-campo-development/app/public/wp-includes/class-wp-hook.php(324): WPML_Gutenberg_Integration->register_strings(Object(WP_Post), Array) #15 /Users/nathanfarleigh/Local Sites/casa-de-campo-development/app/public/wp-includes/class-wp-hook.php(348): WP_Hook->apply_filters('', Array) #16 /Users/nathanfarleigh/Local Sites/casa-de-campo-development/app/public/wp-includes/plugin.php(517): WP_Hook->do_action(Array) #17 /Users/nathanfarleigh/Local Sites/casa-de-campo-development/app/public/wp-content/plugins/sitepress-multilingual-cms/addons/wpml-page-builders/classes/Shared/st/strategy/api-hooks/class-wpml-pb-api-hooks-strategy.php(18): do_action('wpml_page_build...', Object(WP_Post), Array) #18 [internal function]: WPML_PB_API_Hooks_Strategy->register_strings(Object(WP_Post)) #19 /Users/nathanfarleigh/Local Sites/casa-de-campo-development/app/public/wp-content/plugins/sitepress-multilingual-cms/vendor/wpml/fp/core/Invoker/Invoker.php(41): call_user_func_array(Array, Array) #20 /Users/nathanfarleigh/Local Sites/casa-de-campo-development/app/public/wp-content/plugins/sitepress-multilingual-cms/vendor/wpml/fp/core/Fns.php(162): WPMLFPInvoker_Invoker->__invoke(Object(WPML_PB_API_Hooks_Strategy)) #21 [internal function]: WPMLFPFns::WPMLFP{closure}(Object(WPMLFPInvoker_Invoker), Object(WPML_PB_API_Hooks_Strategy), 0) #22 /Users/nathanfarleigh/Local Sites/casa-de-campo-development/app/public/wp-content/plugins/sitepress-multilingual-cms/vendor/wpml/fp/core/functions.php(154): call_user_func_array(Object(Closure), Array) #23 [internal function]: WPMLFP{closure}(Object(WPML_PB_API_Hooks_Strategy), 0) #24 /Users/nathanfarleigh/Local Sites/casa-de-campo-development/app/public/wp-content/plugins/sitepress-multilingual-cms/vendor/wpml/fp/core/Fns.php(151): array_map(Object(Closure), Array, Array) #25 [internal function]: WPMLFPFns::WPMLFP{closure}(Object(Closure), Array) #26 /Users/nathanfarleigh/Local Sites/casa-de-campo-development/app/public/wp-content/plugins/sitepress-multilingual-cms/vendor/wpml/fp/core/functions.php(154): call_user_func_array(Object(Closure), Array) #27 [internal function]: WPMLFPFns::WPMLFP{closure}(Object(Closure), Array) #28 /Users/nathanfarleigh/Local Sites/casa-de-campo-development/app/public/wp-content/plugins/sitepress-multilingual-cms/vendor/wpml/collect/src/Illuminate/Support/Traits/Macroable.php(56): call_user_func_array(Object(Closure), Array) #29 /Users/nathanfarleigh/Local Sites/casa-de-campo-development/app/public/wp-content/plugins/sitepress-multilingual-cms/vendor/wpml/fp/core/Fns.php(156): WPMLFPFns::__callStatic('map', Array) #30 [internal function]: WPMLFPFns::WPMLFP{closure}(Object(WPMLFPInvoker_Invoker), Array) #31 /Users/nathanfarleigh/Local Sites/casa-de-campo-development/app/public/wp-content/plugins/sitepress-multilingual-cms/vendor/wpml/fp/core/functions.php(154): call_user_func_array(Object(Closure), Array) #32 [internal function]: WPMLFPFns::WPMLFP{closure}(Object(WPMLFPInvoker_Invoker), Array) #33 /Users/nathanfarleigh/Local Sites/casa-de-campo-development/app/public/wp-content/plugins/sitepress-multilingual-cms/vendor/wpml/collect/src/Illuminate/Support/Traits/Macroable.php(56): call_user_func_array(Object(Closure), Array) #34 /Users/nathanfarleigh/Local Sites/casa-de-campo-development/app/public/wp-content/plugins/sitepress-multilingual-cms/addons/wpml-page-builders/classes/Shared/st/class-wpml-pb-integration.php(363): WPMLFPFns::__callStatic('each', Array) #35 /Users/nathanfarleigh/Local Sites/casa-de-campo-development/app/public/wp-content/plugins/sitepress-multilingual-cms/addons/wpml-page-builders/classes/Shared/st/class-wpml-pb-integration.php(256): WPML_PB_Integration->with_strategies(Object(WPMLFPInvoker_Invoker)) #36 /Users/nathanfarleigh/Local Sites/casa-de-campo-development/app/public/wp-includes/class-wp-hook.php(324): WPML_PB_Integration->register_all_strings_for_translation(Object(WP_Post)) #37 /Users/nathanfarleigh/Local Sites/casa-de-campo-development/app/public/wp-includes/class-wp-hook.php(348): WP_Hook->apply_filters('', Array) #38 /Users/nathanfarleigh/Local Sites/casa-de-campo-development/app/public/wp-includes/plugin.php(517): WP_Hook->do_action(Array) #39 /Users/nathanfarleigh/Local Sites/casa-de-campo-development/app/public/wp-content/plugins/sitepress-multilingual-cms/classes/translation-jobs/class-wpml-element-translation-package.php(189): do_action('wpml_pb_registe...', Object(WP_Post)) #40 /Users/nathanfarleigh/Local Sites/casa-de-campo-development/app/public/wp-content/plugins/sitepress-multilingual-cms/inc/translation-management/translation-management.class.php(1269): WPML_Element_Translation_Package->do_action_before_creating_translation_package(Object(WP_Post)) #41 /Users/nathanfarleigh/Local Sites/casa-de-campo-development/app/public/wp-content/plugins/sitepress-multilingual-cms/classes/class-wpml-translation-job-factory.php(113): TranslationManagement->send_jobs(Object(WPML_TM_Translation_Batch), 'post', 1) #42 /Users/nathanfarleigh/Local Sites/casa-de-campo-development/app/public/wp-content/plugins/sitepress-multilingual-cms/classes/jobs/Manual.php(164): WPML_Translation_Job_Factory->create_local_job('1059', 'es', NULL, 'post_experience', 1, 'en') #43 /Users/nathanfarleigh/Local Sites/casa-de-campo-development/app/public/wp-content/plugins/sitepress-multilingual-cms/classes/jobs/Manual.php(43): WPMLTMJobsManual->createLocalJob('1059', 'en', 'es', 'post_experience') #44 /Users/nathanfarleigh/Local Sites/casa-de-campo-development/app/public/wp-content/plugins/sitepress-multilingual-cms/vendor/wpml/fp/core/Either.php(207): WPMLTMJobsManual->createOrReuse(Array) #45 /Users/nathanfarleigh/Local Sites/casa-de-campo-development/app/public/wp-content/plugins/sitepress-multilingual-cms/classes/editor/Editor.php(103): WPMLFPRight->map(Array) #46 /Users/nathanfarleigh/Local Sites/casa-de-campo-development/app/public/wp-content/plugins/sitepress-multilingual-cms/classes/menu/translation-queue/class-wpml-translations-queue.php(52): WPMLTMEditorEditor->open(Array) #47 /Users/nathanfarleigh/Local Sites/casa-de-campo-development/app/public/wp-includes/class-wp-hook.php(324): WPML_Translations_Queue->load(Object(WP_Screen)) #48 /Users/nathanfarleigh/Local Sites/casa-de-campo-development/app/public/wp-includes/class-wp-hook.php(348): WP_Hook->apply_filters(NULL, Array) #49 /Users/nathanfarleigh/Local Sites/casa-de-campo-development/app/public/wp-includes/plugin.php(517): WP_Hook->do_action(Array) #50 /Users/nathanfarleigh/Local Sites/casa-de-campo-development/app/public/wp-admin/includes/class-wp-screen.php(424): do_action('current_screen', Object(WP_Screen)) #51 /Users/nathanfarleigh/Local Sites/casa-de-campo-development/app/public/wp-admin/includes/screen.php(243): WP_Screen->set_current_screen() #52 /Users/nathanfarleigh/Local Sites/casa-de-campo-development/app/public/wp-admin/admin.php(213): set_current_screen() #53 {main} thrown in /Users/nathanfarleigh/Local Sites/casa-de-campo-development/app/public/wp-content/plugins/wpml-string-translation/classes/filters/strings-filter/class-wpml-register-string-filter.php on line 193
There has been a critical error on this website. Please check your site admin email inbox for instructions. If you continue to have problems, please try the support forums.

Warning: Array to string conversion in /Users/nathanfarleigh/Local Sites/casa-de-campo-development/app/public/wp-content/plugins/acfml/classes/class-wpml-acf-blocks.php on line 164

Questions:
Can you fix this bug in your plugin please so I can translate repeater fields that have sub field that is another repeater.

I will can give you access to a clone of the site that your colleague Noman already has access.

November 11, 2025 at 5:30 pm #17567926

jasonK-12

I have fixed your plugin to work with nested acf fields

November 11, 2025 at 5:32 pm #17567936

jasonK-12

This is the code I have replaced and now its not critical erroring.
I would sudgest reviewing my changes and think about adding them into your next release as if I need to update your plugin the fix will be lost.
Let me know if you have any questions.

<?php

class WPML_ACF_Blocks implements \IWPML_Backend_Action, \IWPML_Frontend_Action, \IWPML_DIC_Action {

/**
* @var WPML_Post_Translation
*/
private $wpml_post_translations;

/**
* WPML_ACF_Blocks constructor.
*
* @param WPML_Post_Translation $wpml_post_translations
*/
public function __construct( WPML_Post_Translation $wpml_post_translations ) {
$this->wpml_post_translations = $wpml_post_translations;
}

/**
* Initialize hooks.
*/
public function add_hooks() {
add_filter( 'wpml_found_strings_in_block', array( $this, 'add_block_data_attribute_strings' ), 10, 2 );
add_filter( 'wpml_update_strings_in_block', array( $this, 'update_block_data_attribute' ), 10, 3 );
}

/**
* @param array $strings Strings in block.
* @param WP_Block_Parser_Block $block
*
* @return array $strings
*/
public function add_block_data_attribute_strings( array $strings, WP_Block_Parser_Block $block ) {

if ( $this->is_acf_block( $block ) && isset( $block->attrs['data'] ) ) {

if ( ! is_array( $block->attrs['data'] ) ) {
$block->attrs['data'] = array( $block->attrs['data'] );
}

foreach ( $block->attrs['data'] as $field_name => $text ) {

if ( $this->must_skip( $field_name, $text ) ) {
continue;
}

// Recursively process arrays to extract string values
$processed_strings = $this->process_field_recursively( $block, $text, $field_name );
// Filter out any null values (shouldn't happen, but defensive)
$processed_strings = array_filter( $processed_strings, function( $item ) {
return $item !== null;
} );
$strings = array_merge( $strings, $processed_strings );
}
}

return $strings;
}

/**
* Recursively process ACF field values to extract translatable strings.
*
* @param WP_Block_Parser_Block $block
* @param mixed $text Field value (can be string, number, or array)
* @param string $field_name Field name path
*
* @return array Array of string objects
*/
private function process_field_recursively( $block, $text, $field_name ) {
$strings = array();

// Skip arrays - they should be processed recursively
if ( is_array( $text ) ) {
foreach ( $text as $inner_field_name => $inner_text ) {
// Recursively process nested values
$nested_strings = $this->process_field_recursively(
$block,
$inner_text,
$field_name . '/' . $inner_field_name
);
$strings = array_merge( $strings, $nested_strings );
}
} else {
// Only process non-array values (strings, numbers)
// Skip if it's not a translatable value type
if ( $this->valueIsNotTranslatable( $text ) ) {
return $strings;
}

$type = $this->get_text_type( $text );
$string_obj = $this->add_string( $block, $text, $field_name, $type );
if ( $string_obj !== null ) {
$strings[] = $string_obj;
}
}

return $strings;
}

/**
* @param WP_Block_Parser_Block $block
* @param string|numeric $text
* @param string $field_name
* @param string $type
*
* @return object|null Returns null if text is an array (should not happen)
*/
private function add_string( $block, $text, $field_name, $type ) {
// Defensive check: arrays should never reach this method
// If they do, skip them to prevent WPML errors
if ( is_array( $text ) ) {
return null;
}

return (object) array(
'id' => $this->get_string_hash( $block->blockName, $text ),
'name' => $this->get_string_name( $block, $field_name ),
'value' => $text,
'type' => $type,
);
}

/**
* @param WP_Block_Parser_Block $block
* @param array $string_translations
* @param string $lang
*
* @return WP_Block_Parser_Block
*/
public function update_block_data_attribute( WP_Block_Parser_Block $block, array $string_translations, $lang ) {
if ( $this->is_acf_block( $block ) && isset( $block->attrs['data'] ) ) {
foreach ( $block->attrs['data'] as $field_name => $text ) {
if ( $this->is_system_field( $field_name ) ) {
continue;
}
$block = $this->get_block_field_translation_recursive( $block, $string_translations, $lang, $text, $field_name );
}
}
return $block;
}

/**
* @param WP_Block_Parser_Block $block
* @param array $string_translations
* @param string $lang
* @param string|array $text
* @param string $field_name
* @param null|string $inner_field_name
*
* @return mixed
*/
private function get_block_field_translation_recursive( $block, $string_translations, $lang, $text, $field_name, $inner_field_name = null ) {
if ( is_array( $text ) ) {
foreach ( $text as $inner_field_name => $inner_text ) {
$block = $this->get_block_field_translation_recursive( $block, $string_translations, $lang, $inner_text, $field_name, $inner_field_name );
}
} else {
$block = $this->get_block_field_translation( $block, $string_translations, $lang, $text, $field_name, $inner_field_name );
}
return $block;
}

/**
* @param WP_Block_Parser_Block $block
* @param array $string_translations
* @param string $lang
* @param string $text
* @param string $field_name
* @param null|string $inner_field_name
*
* @return mixed
*/
private function get_block_field_translation( $block, $string_translations, $lang, $text, $field_name, $inner_field_name = null ) {
$string_hash = $this->get_string_hash( $block->blockName, $text );

if ( isset( $string_translations[ $string_hash ][ $lang ]['status'] )
&& ICL_TM_COMPLETE === (int) $string_translations[ $string_hash ][ $lang ]['status']
&& isset( $string_translations[ $string_hash ][ $lang ]['value'] )
) {
if ( $inner_field_name ) {
$block->attrs['data'][ $field_name ][ $inner_field_name ] = $string_translations[ $string_hash ][ $lang ]['value'];
} else {
$block->attrs['data'][ $field_name ] = $string_translations[ $string_hash ][ $lang ]['value'];
}
}

return $block;
}

/**
* @param WP_Block_Parser_Block $block
*
* @return bool
*/
private function is_acf_block( WP_Block_Parser_Block $block ) {
return strpos( $block->blockName, 'acf/' ) === 0 ||
function_exists( 'acf_has_block_type' ) && acf_has_block_type( $block->blockName );
}

/**
* @param string $block_name
* @param string|array $text
*
* @return string
*/
private function get_string_hash( $block_name, $text ) {
// Convert array to string for hashing
if ( is_array( $text ) ) {
$text = serialize( $text );
}
return md5( $block_name . $text );
}

/**
* @param WP_Block_Parser_Block $block
* @param string $field_name
*
* @return string
*/
private function get_string_name( WP_Block_Parser_Block $block, $field_name ) {
return $block->blockName . '/' . $field_name;
}

/**
* @param string $field_name
*
* @return bool
*/
private function is_system_field( $field_name ) {
return strpos( $field_name, '_' ) === 0;
}

/**
* @param string|array $text ACF field value.
*
* @return string
*/
private function get_text_type( $text ) {
$type = 'LINE';
if ( is_array( $text ) ) {
$type = 'array';
} elseif ( strip_tags( $text ) !== $text ) {
$type = 'VISUAL';
} elseif ( strpos( $text, "\n" ) !== false ) {
$type = 'AREA';
}
return $type;
}
/**
* @param string $fieldName ACF field name.
* @param string $text ACF field value.
*
* @return bool
*/
private function must_skip( $fieldName, $text ) {
return $this->is_system_field( $fieldName ) ||
$this->valueIsNotTranslatable( $text ) ||
! $this->isTranslatableInPreferences( $fieldName );
}

/**
* Checks if ACF field translation preferences is set to Translate or Copy once.
*
* @param string $fieldName ACF field name.
*
* @return bool
*/
private function isTranslatableInPreferences( $fieldName ) {
$acfField = acf_get_field( $fieldName );
if ( ! $acfField ) {
$acfField = $this->maybeGetSubfield( $fieldName );
}
if ( isset( $acfField['wpml_cf_preferences'] ) ) {
return (int) $acfField['wpml_cf_preferences'] === WPML_TRANSLATE_CUSTOM_FIELD;
}
return true;
}

/**
* Split field name by "_(digit)_" and try to return ACF field object for last part.
*
* Handles cases for repeater and flexible subfields.
*
* @param string $fieldName Processed field name.
*
* @return array|false ACF field object (array) or false.
*/
private function maybeGetSubfield( $fieldName ) {
$fieldNameParts = preg_split( '/_\d_/', $fieldName );
if ( is_array( $fieldNameParts ) && 1 < count( $fieldNameParts ) ) {
return acf_get_field( end( $fieldNameParts ) );
}
return false;
}

/**
* Checks if field value is in the format supported by Translation Editor.
*
* @param mixed $text
*
* @return bool
*/
private function valueIsNotTranslatable( $text ) {
return ! is_string( $text ) &&
! is_numeric( $text ) &&
! is_array( $text );
}

}

November 12, 2025 at 8:36 am #17569313

Bruno Kos
WPML Supporter since 12/2018

Languages: English (English ) German (Deutsch ) French (Français )

Timezone: Europe/Zagreb (GMT+01:00)

Thank you very much for the detailed update and for sharing the custom code solution!

I've forwarded this to our 2nd tier development team so they can review your changes and evaluate them for inclusion in a future ACFML release. I’ll keep you posted as soon as I hear back from them.

November 12, 2025 at 12:26 pm #17570527

Bruno Kos
WPML Supporter since 12/2018

Languages: English (English ) German (Deutsch ) French (Français )

Timezone: Europe/Zagreb (GMT+01:00)

I’ve linked it to an existing issue and shared your code with our developers. They’ll review it and we’ll update you once there’s progress.