temporalio/temporal · error

registrable component validation error: search attribute fie

Error message

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

What it means

This panic fires when two SearchAttribute entries on the same RegistrableComponent map to the same underlying field (the visibility column name), even if their aliases differ. fieldToAlias is also one-to-one, so two aliases pointing at one field would corrupt query mapping; registration panics to prevent the ambiguous field->alias mapping.

Source

Thrown at chasm/registrable_component.go:153

				//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
// component's struct definition, such as configurations.
//
// Keys need to be globally unique across components. Conflicting keys across will cause component registration to fail.
//

View on GitHub (pinned to bde624efd1)

Solutions

  1. Give each SearchAttribute a unique field name
  2. Remove the redundant attribute definition and reuse the existing alias for the field
  3. Verify field constants/definitions aren't accidentally shared between attribute declarations

Example fix

// before
chasm.NewSearchAttribute("OrderStatus", "OrderStatus", ...),
chasm.NewSearchAttribute("Status", "OrderStatus", ...) // same field
// after
chasm.NewSearchAttribute("OrderStatus", "OrderStatus", ...) // one alias per field
Defensive patterns

Strategy: validation

Validate before calling

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

Prevention

When it happens

Trigger: Calling chasm.WithSearchAttributes with two SearchAttributes having distinct aliases but the same definition().field value (field already present in fieldToAlias).

Common situations: Declaring the same column with two alias spellings (e.g. 'OrderStatus' and 'order_status' both mapping to field 'OrderStatus'); merging attribute definitions from two components that share a field name; typos in field constants pointing at an existing column.

Related errors


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