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

  1. Use exactly one named input on the external transform, or align tag naming with what the expansion service produces.
  2. Upgrade/patch the external SDK's expansion service so it does not rename multiple input tags.
  3. 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

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


AI-assisted analysis of apache/beam@12126d8942 (2026-09-13). Data as JSON: /api/errors/93737053defa068b. Report an issue: GitHub.