Skip to content

Fix #462: document that replace-field-action only renames top level fields - #2995

Merged
oscerd merged 1 commit into
apache:mainfrom
oscerd:ci-issue-462
Sep 1, 2026
Merged

Fix #462: document that replace-field-action only renames top level fields#2995
oscerd merged 1 commit into
apache:mainfrom
oscerd:ci-issue-462

Conversation

@oscerd

@oscerd oscerd commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

Fixes #462.

The report is accurate and still reproduces four years on. This documents the real contract rather than implying a capability the Kamelet does not have — the behaviour itself is not ours to change.

Reproduced

Using the exact example from the issue, through the shipped Kamelet:

renames in out
message:msg (top level) {"message":{"Hola":"mundo"}} {"msg":{"Hola":"mundo"}}
Hola:Hi (nested) {"message":{"Hola":"mundo"}} {"message":{"Hola":"mundo"}}

The nested rename is a silent no-op — no error, no warning, body unchanged.

Why

replace-field-action is a thin wrapper around org.apache.camel.component.kafka.transform.ReplaceField. Its process() walks the top level map and nothing else:

for (Map.Entry<Object, Object> entry : body.entrySet()) {
    final String fieldName = (String) entry.getKey();
    if (filterNames(fieldName, enabledFields, disabledFields)) {
        final Object fieldValue = entry.getValue();
        updatedBody.put(renameOptional(fieldName, renamingMap), fieldValue);
    }
}

A nested object arrives as fieldValue and is put back untouched — the transform never descends into it. enabled and disabled filter on the same top level keys via filterNames, so the limitation applies to all three properties, not just renames.

Scope

Supporting nested paths means changing camel-kafka, not this template — per the contributor guidelines that is apache/camel territory. It would also be a semantic extension rather than a bug fix: the transform mirrors the Kafka Connect ReplaceField SMT, which is likewise top level only.

So this PR makes the documented contract match the implemented one:

-    description: Replace field with a different key in the message in transit.
+    description: |-
+      Replace field with a different key in the message in transit.
+
+      Only top level fields are considered. Fields nested inside an object are passed through
+      untouched, so a rename that names a nested field has no effect.

plus the same clarification on renames, enabled and disabled.

That is deliberately modest. The reason this issue stayed open for four years is that nothing told the user the limitation existed — the property descriptions read as though any field could be renamed. Saying so up front is the part that actually prevents recurrence.

Verification

script/validator reports no errors, script/generator produces no doc changes beyond the regenerated nav.adoc (unchanged here), and mvn clean install passes from the repository root. No template or behavioural change — descriptions only.

Note for reviewers

If you would rather have nested support than a documented limitation, the right move is an issue against apache/camel for ReplaceField, and I am happy to open it and reference this. I did not assume that, because changing the transform would also change behaviour for every existing user of the SMT-compatible semantics.

I checked the sibling transforms (DropField, HoistField, MaskField, ValueToKey) to see whether they share the limitation, but my check was inconclusive and I have not claimed anything about them here. Worth a look separately if this wording is agreed.


Claude Code on behalf of Andrea Cosentino

…evel fields

The Kamelet delegates to org.apache.camel.component.kafka.transform.ReplaceField,
whose process() iterates the top level map only:

    for (Map.Entry<Object, Object> entry : body.entrySet()) {
        final String fieldName = (String) entry.getKey();
        if (filterNames(fieldName, enabledFields, disabledFields)) {
            final Object fieldValue = entry.getValue();
            updatedBody.put(renameOptional(fieldName, renamingMap), fieldValue);
        }
    }

Nested objects are carried across as opaque values and never descended into,
so naming a nested field is silently a no-op. Reproduced with the example
from the issue:

    renames=message:msg  {"message":{"Hola":"mundo"}} -> {"msg":{"Hola":"mundo"}}
    renames=Hola:Hi      {"message":{"Hola":"mundo"}} -> {"message":{"Hola":"mundo"}}

Supporting nested paths would be a change to camel-kafka, not to this
template, so this documents the actual contract instead of implying a
capability the Kamelet does not have. enabled and disabled filter on the
same top level keys and are worded to match.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@oscerd
oscerd merged commit f1db835 into apache:main Sep 1, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

replace-field-action does not replace nested fields

1 participant