apache/beam · error · Error
Ambiguous renaming of tags.
Error message
Ambiguous renaming of tags.
What it means
After expansion, splice() reconciles input tag names between the original transformProto and the service's response.transform. If the response renamed tags such that more than one new (unrecognized) tag appears, the single-renaming heuristic cannot disambiguate, so it throws 'Ambiguous renaming of tags.'
Source
Thrown at sdks/typescript/src/apache_beam/transforms/external.ts:280
) {
for (const [id, proto] of Object.entries(src)) {
if (id.startsWith(namespace)) {
dest[id] = proto;
}
}
}
function difference<T>(a: Set<T>, b: Set<T>): T[] {
return [...a].filter((x) => !b.has(x));
}
// Some SDKs enforce input naming conventions.
const newTags = difference(
new Set(Object.keys(response.transform!.inputs)),
new Set(Object.keys(transformProto.inputs)),
);
if (newTags.length > 1) {
throw new Error("Ambiguous renaming of tags.");
} else if (newTags.length === 1) {
const missingTags = difference(
new Set(Object.keys(transformProto.inputs)),
new Set(Object.keys(response.transform!.inputs)),
);
transformProto.inputs[newTags[0]] = transformProto.inputs[missingTags[0]];
delete transformProto.inputs[missingTags[0]];
}
// PCollection ids may have changed as well.
const renamedInputs = Object.fromEntries(
Object.keys(response.transform!.inputs).map((k) => [
response.transform!.inputs[k],
transformProto.inputs[k],
]),
);
response.transform!.inputs = Object.fromEntries(
Object.entries(response.transform!.inputs).map(([k, v]) => [View on GitHub (pinned to 12126d8942)
Solutions
- Use exactly one named input on the external transform, or align tag naming with what the expansion service produces.
- Upgrade/patch the external SDK's expansion service so it does not rename multiple input tags.
- Pre-map input tags before expansion so no renaming occurs.
Example fix
// before
external.withInputs({ a: pc1, b: pc2 }); // service renames both tags -> ambiguous
// after
external.withInputs({ input: pc1 }); // single tag, rename inference unambiguous Defensive patterns
Strategy: try-catch
Validate before calling
// Inspect the expanded response's input tags before splicing
const respTags = Object.keys(response.transform.inputs);
const origTags = Object.keys(transformProto.inputs);
const newTags = respTags.filter(t => !origTags.includes(t));
if (newTags.length > 1) throw new Error("Multiple renamed input tags; adjust transform naming"); Type guard
null
Try / catch
try {
await external.expandInternalAsync(...);
} catch (e) {
if (e.message === "Ambiguous renaming of tags.") {
console.error("Expansion service renamed multiple inputs; use single-tag inputs or matching names.");
} else throw e;
} Prevention
- Use a single named input on external transforms when possible
- Match input tag names to what the remote SDK produces
- Keep external SDK versions aligned with the TypeScript SDK
When it happens
Trigger: expandInternalAsync -> splice where Object.keys(response.transform.inputs) contains more than one tag not present in the original transformProto.inputs.
Common situations: A foreign-language SDK's expansion service renames multiple input tags to comply with its own naming conventions, breaking the TypeScript SDK's tag-rename inference.
Related errors
- ${response.error}
- mismatch'd counts between External tags (%v) and inputs (%v)
- mismatch'd counts between External tags (%v) and outputs (%v
- failed to expand cross language transform for edge: %v
- Could not find coder for URN " + urn
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/93737053defa068b.
Report an issue: GitHub.