Feature Request: Auto-link resources by name for PM-in-UI workflows
Summary
When Product Managers create events/categories in the RudderStack UI and engineers use the CLI to manage tracking plans, there's significant friction due to the requirement for explicit metadata.import stanzas with remote_id mappings. This creates maintenance burden and error-prone manual steps.
Current Workflow
Our team follows this workflow:
- PM creates events/categories in the RudderStack staging UI
- Engineer imports using
rudder-cli import workspace
- Engineer manually adds
metadata.import sections with remote_id mappings to link local definitions to remote resources
- Engineer pushes to git
- GitHub Action applies to production on merge
The Problem
Resources created in the UI don't have external_id set, so the CLI treats them as "invisible" when loading remote state:
// category.go line 170
categories, err := p.client.GetCategories(ctx, catalog.ListOptions{HasExternalID: lo.ToPtr(true)})
This means engineers must:
- Run
import workspace to get resources into an imported/ directory
- Manually copy
remote_id values from imported files
- Add
metadata.import.workspaces stanzas to their existing files
- For each workspace (staging, production), repeat this process with different
remote_id values
Example of the friction
A simple category import requires this boilerplate:
metadata:
name: event-categories
import:
workspaces:
- workspace_id: "STAGING_WORKSPACE_ID"
resources:
- local_id: "canvas"
remote_id: "cat_3xxxxxxxxxxxxexxxxxxxxxxxx"
- workspace_id: "PRODUCTION_WORKSPACE_ID"
resources:
- local_id: "canvas"
remote_id: "cat_DIFFERENT_PROD_ID"
This scales linearly - every PM-created resource needs entries for every workspace.
Error we encounter without this
Error: syncing the state: creating category resource in upstream catalog:
sending request: http status code: 400, error code: '',
error: 'Category with name Canvas already exists'
Proposed Solutions
Option 1: --match-by-name flag (Recommended)
Add a flag to apply that enables name-based matching for resources without external_id:
rudder-cli tp apply -l . --match-by-name
Behavior:
- When a local resource doesn't exist in remote state (no matching
external_id)
- AND a remote resource with the same
name exists (without external_id)
- Prompt user: "Found existing 'Canvas' category. Link and set external_id? [y/n]"
- If yes, perform an import operation instead of create
Option 2: --auto-link flag with interactive confirmation
rudder-cli tp apply -l . --auto-link
# Output:
# The following resources exist remotely but aren't linked:
# - category:canvas (remote: cat_37tIcdNnXjm90UeONAx737RgfJm)
# - event:canvas-project-created (remote: ev_37tL0Edtrdzhz8TWoXm1Jj9Y5Hh)
#
# Link these resources? [y/n]
Option 3: Import-and-merge mode
rudder-cli import workspace -l . --merge
Instead of writing to imported/ directory, automatically:
- Match imported resources to existing local definitions by
id
- Add/update
metadata.import sections in-place
- Report what was merged
Option 4: Workspace-agnostic external_id
If the CLI set external_id on resources at creation time AND the UI also set external_id, resources would be trackable across both interfaces without explicit mappings.
Environment
- CLI Version: 0.11.2
- Workflow: PM creates in staging UI → Engineer imports → GitHub Action applies to production
Workaround
Currently we:
- Temporarily remove new resources from local files
- Run
import workspace
- Copy
remote_id values from imported files
- Restore local files with added
metadata.import stanzas
- Repeat for each workspace
This is error-prone and doesn't scale.
Impact
- Developer time: ~10-15 minutes per resource for the import dance
- Error prone: Manual copy-paste of UUIDs
- Maintenance burden: Import stanzas grow linearly with resources × workspaces
- Onboarding friction: New engineers struggle with this non-obvious workflow
Related
- The
HasExternalID: true filter in LoadResourcesFromRemote methods is the root cause
- Name-based matching would need collision handling (prompt user if ambiguous)
Feature Request: Auto-link resources by name for PM-in-UI workflows
Summary
When Product Managers create events/categories in the RudderStack UI and engineers use the CLI to manage tracking plans, there's significant friction due to the requirement for explicit
metadata.importstanzas withremote_idmappings. This creates maintenance burden and error-prone manual steps.Current Workflow
Our team follows this workflow:
rudder-cli import workspacemetadata.importsections withremote_idmappings to link local definitions to remote resourcesThe Problem
Resources created in the UI don't have
external_idset, so the CLI treats them as "invisible" when loading remote state:This means engineers must:
import workspaceto get resources into animported/directoryremote_idvalues from imported filesmetadata.import.workspacesstanzas to their existing filesremote_idvaluesExample of the friction
A simple category import requires this boilerplate:
This scales linearly - every PM-created resource needs entries for every workspace.
Error we encounter without this
Proposed Solutions
Option 1:
--match-by-nameflag (Recommended)Add a flag to
applythat enables name-based matching for resources withoutexternal_id:rudder-cli tp apply -l . --match-by-nameBehavior:
external_id)nameexists (withoutexternal_id)Option 2:
--auto-linkflag with interactive confirmationOption 3: Import-and-merge mode
rudder-cli import workspace -l . --mergeInstead of writing to
imported/directory, automatically:idmetadata.importsections in-placeOption 4: Workspace-agnostic external_id
If the CLI set
external_idon resources at creation time AND the UI also setexternal_id, resources would be trackable across both interfaces without explicit mappings.Environment
Workaround
Currently we:
import workspaceremote_idvalues from imported filesmetadata.importstanzasThis is error-prone and doesn't scale.
Impact
Related
HasExternalID: truefilter inLoadResourcesFromRemotemethods is the root cause