temporalio/temporal · error

registrable component validation error: search attribute ali

Error message

registrable component validation error: search attribute alias %q is already defined

What it means

This panic occurs when two SearchAttribute entries passed to WithSearchAttributes on the same RegistrableComponent use the same alias. The mapper stores aliasToField one-to-one, so a duplicate alias would silently overwrite the earlier mapping; registration instead panics to surface the conflict at startup.

Source

Thrown at chasm/registrable_component.go:149

				continue
			}

			if sadefs.IsChasmSystem(alias) {
				//nolint:forbidigo
				panic(fmt.Sprintf("registrable component validation error: CHASM search attribute alias %q is a CHASM system search attribute", alias))
			}
			if !sadefs.IsSystem(alias) && sadefs.IsReserved(alias) {
				//nolint:forbidigo
				panic(fmt.Sprintf("registrable component validation error: CHASM search attribute alias %q is a reserved search attribute", alias))
			}

			if _, ok := rc.searchAttributesMapper.systemAliasToField[alias]; ok {
				//nolint:forbidigo
				panic(fmt.Sprintf("registrable component validation error: CHASM search attribute alias %q is already defined as a system search attribute alias", alias))
			}
			if _, ok := rc.searchAttributesMapper.aliasToField[alias]; ok {
				//nolint:forbidigo
				panic(fmt.Sprintf("registrable component validation error: search attribute alias %q is already defined", alias))
			}
			if _, ok := rc.searchAttributesMapper.fieldToAlias[field]; ok {
				//nolint:forbidigo
				panic(fmt.Sprintf("registrable component validation error: search attribute field %q is already defined", field))
			}

			rc.searchAttributesMapper.aliasToField[alias] = field
			rc.searchAttributesMapper.fieldToAlias[field] = alias
			rc.searchAttributesMapper.saTypeMap[field] = valueType
		}
	}
}

// WithContextValues allows specifying key-value pairs that will be available in the Context
// via the Value() method whenever the chasm framework starts, updates, reads, polls, executes or
// validates tasks on a component.
//
// This is useful for propagating values needed for those processing logic but are not avaiable via the

View on GitHub (pinned to bde624efd1)

Solutions

  1. Deduplicate the SearchAttribute list before passing it to WithSearchAttributes
  2. Rename one of the colliding aliases to a unique name
  3. Centralize the component's search attribute definitions in one place so duplicates are obvious

Example fix

// before
chasm.WithSearchAttributes(saStatus, saOrderStatus) // both alias "Status"
// after
chasm.WithSearchAttributes(saStatus) // single definition per alias
Defensive patterns

Strategy: validation

Validate before calling

seen := map[string]bool{}
for _, sa := range attrs {
    if seen[sa.definition().alias] {
        return fmt.Errorf("duplicate alias %q", sa.definition().alias)
    }
    seen[sa.definition().alias] = true
}

Prevention

When it happens

Trigger: Calling chasm.WithSearchAttributes(sa1, sa2, ...) where sa1.definition().alias == sa2.definition().alias, or calling WithSearchAttributes twice on the same component with a repeated alias (alias already present in aliasToField).

Common situations: Copy-pasting a SearchAttribute list where an attribute was declared twice; two team members adding attributes with the same short name (e.g. 'Status'); refactoring that merged two attribute lists without deduplicating.

Related errors


AI-assisted analysis of temporalio/temporal@bde624efd1 (2026-09-01). Data as JSON: /api/errors/6f261140e8c6b849. Report an issue: GitHub.