ACF never stores a field as a single row. Alongside the value it writes a reference row holding the field key, and for a repeater it writes one row per index per sub-field. Those reference rows are how ACF knows which field definition a value belongs to.
Write the value row directly with post meta and the reference rows stay behind, pointing at the old state. ACF can no longer read its own data — and nothing reports a problem, because the write did succeed. custom-fields/update-acf-field goes through update_field(), which keeps every row in step.
At a glance
| Ability | custom-fields/update-acf-field |
| Toolset | Advanced Custom Fields — toolset/acf |
| Group | Field Values |
| Requires | Advanced Custom Fields (free edition is enough) |
| Capability | manage_options |
| Safety | Writes data |
| Repeatable | Idempotent — running it twice leaves the same result |
| Ships in | AcrossAI Abilities Manager 0.0.34 and later |
Why this and not post meta
The target pair and the selector work exactly as they do on the read: a field name or field key, against a post, user, term, comment or the options store.
The shape of value follows the field type. Text and number fields take a scalar. A repeater takes an array of row objects keyed by sub-field name. A relationship takes a post ID or an array of them. An image takes an attachment ID. Read the field first if you are not certain which.
After the write the ability re-reads the field and returns it, so the response shows what ACF actually stored rather than what was sent. For most types those match; for dates, or a relationship given slugs instead of IDs, the stored form is the one that matters.
Input
| Name | Type | Required | What it is |
|---|---|---|---|
target_type | string | No — defaults to post | What the value is attached to: post, user, term, comment or option. post covers pages and any custom post type. |
target_id | integer | string | Yes, for post, user, term and comment | The ID of the target. Optional for option, where it names a specific options page; omit it for the default options store. |
selector | string | Yes | Field name or field key. |
value | string | number | boolean | array | object | null | Yes | The new value. Its shape follows the field type. |
apply_wp_slash | boolean | No — defaults to true | Runs wp_slash() over your strings before writing, so literal backslashes survive. Set it false only when you have already slashed the payload yourself. |
What comes back
| Name | Type | What it is |
|---|---|---|
field | object | The field as ACF stored it, re-read after the write. |
updated | boolean | True when the write went through. |
success | boolean | Whether the call completed. |
message | string | A one-line summary of what happened, suitable for showing a human. |
error_code | string | Present only on failure — a stable machine-readable reason, such as a missing field, a wrong field type or an unmet confirmation. |
Example
Ask your assistant:
Set the subtitle field on post 412 to “Built for teams that ship weekly”.
It resolves to one call:
{
"ability": "custom-fields/update-acf-field",
"parameters": {
"target_type": "post",
"target_id": 412,
"selector": "subtitle",
"value": "Built for teams that ship weekly"
}
}Worth knowing
- Idempotent by design — writing the same value twice leaves the same state, so a retry after a dropped connection is safe.
- Read with
custom-fields/get-acf-fieldfirst when the value is complex. A repeater written from a guess replaces every row, including the ones you meant to keep. - ACF block values are not field values. They live in the post content as part of the block markup — use
blocks/update-acf-block-datafor those. - Changing several fields on the same target?
custom-fields/update-acf-fieldsdoes it in one call and reports per-field success.
Related abilities
- Get ACF Field Value — read the current value so the write is idempotent
- Update Multiple ACF Field Values — several fields, one call
- Update ACF Block Data — the right tool for values inside a block
Get the plugins:
AcrossAI Abilities Manager · AcrossAI MCP Manager
Browse the rest: Every ability, by category