Problem/Motivation

When using recipe config actions that utilize `CreateForEachBundle` (such as `createForEachIfNotExists`, `createForEach`, or any action using wildcard config names like `node.type.*`), a TypeError occurs if the configuration being processed contains fields defined as `integer` or `boolean` types in the config schema.

Error:
TypeError: str_replace(): Argument #3 ($subject) must be of type array|string, int given
in CreateForEachBundle.php on line 128

Steps to reproduce

1. Create a Drupal recipe with a `createForEachIfNotExists` action targeting a wildcard pattern (e.g., `node.type.*`)
2. Include configuration that references entities with integer or boolean schema types (e.g., `ai_automator` config with `weight: 100` and `edit_mode: false`)
3. Apply the recipe using `php web/core/scripts/drupal recipe recipes/your_recipe`
4. Observe TypeError

Example recipe

Root Cause:

1. Config Schema Typing: When configuration is loaded and validated against config schemas (e.g., `ai_automators.schema.yml`), fields typed as `integer` or `boolean` are converted from YAML to native PHP integers and booleans. This is correct and expected behavior.

2. Array Key Processing: During the schema validation process, if configuration data structures contain numeric keys, these keys may be represented as PHP integers (depending on how YAML is parsed and validated).

3. Missing Type Check: The `CreateForEachBundle::replacePlaceholders()` method attempts to perform `str_replace()` on ALL array keys without first checking if the key is a string. When it encounters an integer key, `str_replace()` throws a TypeError because it only accepts string or array types for its third argument.

Proposed resolution

Thanks to guidance from @phenaproxima,

Wrap the str_replace() call in an is_string() check. Only perform placeholder replacement on string keys and values, since non-string types (integers, booleans, floats, null) cannot contain placeholders anyway.

Remaining tasks

MR to follow

User interface changes

Introduced terminology

API changes

Data model changes

Release notes snippet

Issue fork drupal-3550174

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

thejimbirch created an issue. See original summary.

thejimbirch’s picture

Issue summary: View changes
thejimbirch’s picture

Title: TypeError in CreateForEachBundle::replacePlaceholders() when processing config with integer or boolean schema types » TypeError in CreateForEachBundle when processing config with integer or boolean schema types
Issue summary: View changes

thejimbirch’s picture

Status: Active » Needs review

MR added.

phenaproxima’s picture

Status: Needs review » Needs work
Issue tags: +Needs tests

No objections to that fix. Needs a test though!

thejimbirch’s picture

Status: Needs work » Active

Calling all testers! That is beyond my skillset.

b_sharpe’s picture

Assigned: Unassigned » b_sharpe
b_sharpe’s picture

Status: Active » Needs review

Updated the existing test as it's really the same thing, just we didn't have non-string values in it before. Simplified the method a little as well to make more readable.

phenaproxima’s picture

Status: Needs review » Needs work
Issue tags: -Needs tests

Couple minor points about comments, otherwise RTBC.

b_sharpe’s picture

Status: Needs work » Needs review
thejimbirch’s picture

Since this is a bug in the existing code base, would it be possible to bring this down to 10.x also?

We're needing this in the AI initiative SEO Optimizer recipe.

phenaproxima’s picture

I'm not sure the %bundle replacement in keys even exists in 10.x at all, but if it does, then IMHO it should be backported.

phenaproxima’s picture

Status: Needs review » Reviewed & tested by the community

One suggestion for clarity, RTBC otherwise.

alexpott’s picture

Status: Reviewed & tested by the community » Fixed

Committed and pushed f4b0ecfb98d to 11.x and 2aa1f42b032 to 11.2.x. Thanks!

Now that this issue is closed, please review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, please credit people who helped resolve this issue.

  • alexpott committed 2aa1f42b on 11.2.x
    Issue #3550174 by thejimbirch, phenaproxima, b_sharpe: TypeError in...

  • alexpott committed f4b0ecfb on 11.x
    Issue #3550174 by thejimbirch, phenaproxima, b_sharpe: TypeError in...

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.