Sheraz AhmadSenior Web Developer
Let's talk

ACF Repeater Field Not Saving? 5 Causes and How to Fix Each

Diagnose and fix your acf repeater field not saving issue with this senior developer guide covering PHP, JavaScript, max_input_vars, and REST API payloads.

When an acf repeater field not saving issue strikes your WordPress site, it usually points to a silent PHP limit, a mismatched field key, or a frontend state bug in headless implementations. Here is how to systematically find the root cause and apply the correct fix.

Quick answer

  • PHP Input Limits: Increase max_input_vars in your php.ini file if large repeaters truncate on save.
  • Incorrect Function: Use update_field('field_name', $value, $post_id) instead of raw update_post_meta().
  • Field Key Mismatches: Clear local JSON sync conflicts if field groups drift between environments.
  • REST API Payload Shape: Send repeater rows as indexed arrays when saving via the WordPress REST API or Next.js.

Increase max_input_vars in PHP and Nginx

Advanced Custom Fields saves repeaters by submitting hundreds of individual input fields via POST requests. If your repeater contains more than roughly thirty rows with multiple sub-fields, PHP silently drops the excess data before it ever reaches WordPress.

Check your server logs or run phpinfo() to see your current max_input_vars setting. The default limit of 1000 is frequently exhausted by complex page builders and nested repeaters.

; Add this to your php.ini or .user.ini file
max_input_vars = 5000

If you run an Nginx and PHP-FPM stack, ensure your web server block does not impose secondary limits on POST body size or request header lengths. Restart your PHP-FPM service after modifying configuration files.

Switch from update_post_meta to update_field

Developers often attempt to save repeater data using WordPress core functions like update_post_meta(). This fails because ACF serializes repeater data into specific formats and stores companion metadata keys for every row index.

Always use the native ACF API function. The ACF engine handles the serialization, updates the row count meta, and triggers necessary hooks.

// Correct approach for saving a repeater programmatically
$rows = array(
    array(
        'title' => 'First Row Title',
        'link'  => 123,
    ),
    array(
        'title' => 'Second Row Title',
        'link'  => 456,
    ),
);

update_field('my_repeater_field_name', $rows, $post_id);

If you pass raw arrays to update_post_meta(), the data will display correctly in code but break completely inside the WordPress admin edit screen.

Fix Local JSON Sync and Field Key Collisions

If you track ACF field groups using Local JSON, database IDs and field keys can drift between local development, staging, and production servers. When a user clicks update, ACF expects the submitted field keys to match the active field group configuration.

Open your field group in the WordPress admin and verify that the field name and key match your code or JSON definitions. If ACF detects an orphaned or conflicting field key, it drops the submitted POST array during sanitization.

Gotcha: Never modify generated ACF field keys (field_5f8a...) by hand in your database or JSON files. If you need to rename a field, change the field name attribute while keeping the unique key intact.

Format REST API and Next.js Payloads Correctly

When building headless applications with Next.js and the WordPress REST API, saving repeater fields requires sending a strictly formatted array of objects. Passing JSON strings or improperly indexed arrays causes the mutation to fail silently or return a 400 Bad Request error.

ACF exposes fields to the core REST API under an acf key, but only when Show in REST API is enabled in the field group settings. Send the repeater as an array of row objects keyed by sub-field name.

// Example Next.js Server Action payload for updating a repeater
const payload = {
  acf: {
    my_repeater_field_name: [
      { title: "Client Update", link: "https://example.com" },
      { title: "Quarterly Report", link: "https://example.com/report" }
    ]
  }
};

await fetch(`${process.env.NEXT_PUBLIC_WP_URL}/wp-json/wp/v2/posts/${postId}`, {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': `Bearer ${token}`
  },
  body: JSON.stringify(payload)
});

Ensure your custom endpoints or GraphQL mutations wrap ACF update functions within proper user capability checks (current_user_can('edit_post', $postId)) to prevent permission errors from blocking the write operation.

Handle Nested Repeaters and Flexible Content Blocks

Nested repeaters generate exponentially more POST variables. If your repeater contains another repeater or lives inside a Flexible Content layout, your max_input_vars requirement multiplies rapidly.

Inspect your browser developer tools under the Network tab when saving the post. Check the Payload tab of the POST request to verify that all sub-field inputs like acf[field_1][0][field_2][0][sub_field] are present in the outgoing request.

If fields disappear halfway down the list, PHP truncated the request due to max_input_vars. If the fields arrive at the server but fail to save, hook into acf/update_value to debug the incoming array structure.

add_filter('acf/update_value/name=my_nested_repeater', function($value, $post_id, $field) {
    // Uncomment to inspect incoming repeater payload during save
    // error_log(print_r($value, true));
    return $value;
}, 10, 3);

Checklist

  • Raise max_input_vars to 5000 in your PHP configuration.
  • Replace any raw update_post_meta() calls with update_field().
  • Confirm Local JSON files are synced and field keys match database records.
  • Inspect browser Network tab to verify all repeater inputs are submitted in the POST body.
  • Verify user capabilities and REST API authentication tokens if saving headlessly.

Frequently asked questions

Why does my ACF repeater reset to zero rows upon saving?

This usually happens when your PHP max_input_vars limit is too low, causing the server to truncate the incoming POST request before saving. Increase max_input_vars in your php.ini file to resolve the issue.

How do I update an ACF repeater field programmatically with PHP?

Use the native ACF function update_field('field_name', $array_of_rows, $post_id) instead of update_post_meta. Passing raw data to update_post_meta bypasses ACF serialization and breaks the admin edit screen.

How do I save ACF repeater fields via the WordPress REST API?

Send an authenticated POST request with an array of objects representing each repeater row, mapping directly to the field name inside your request body payload.

Reference documentation

Drafted with AI assistance. Code targets current WordPress, WooCommerce and Next.js APIs; test changes on a staging site before production.

Need a fast, modern website?

I'm Sheraz Ahmad, a senior WordPress and headless Next.js developer with 7+ years of shipping high-performance sites. Open to permanent roles, contracts and freelance projects.

Let's talk