temporalio/temporal · critical

<dynamic namespace archival state err>

Error message

<dynamic namespace archival state err>

What it means

The sibling of the cluster-state panic: NewArchivalConfig in common/archiver/archival_metadata.go calls getNamespaceArchivalState on the namespaceDefaultStateStr and panics if it cannot be parsed. The thrown value "<dynamic namespace archival state err>" wraps the parser's error. Same fail-fast philosophy — invalid namespace default archival state at construction time is fatal.

Source

Thrown at common/archiver/archival_metadata.go:116

func (metadata *archivalMetadata) GetVisibilityConfig() ArchivalConfig {
	return metadata.visibilityConfig
}

// NewArchivalConfig constructs a new valid ArchivalConfig
func NewArchivalConfig(
	staticClusterStateStr string,
	dynamicClusterState dynamicconfig.StringPropertyFn,
	enableRead dynamicconfig.BoolPropertyFn,
	namespaceDefaultStateStr string,
	namespaceDefaultURI string,
) ArchivalConfig {
	staticClusterState, err := getClusterArchivalState(staticClusterStateStr)
	if err != nil {
		panic(err)
	}
	namespaceDefaultState, err := getNamespaceArchivalState(namespaceDefaultStateStr)
	if err != nil {
		panic(err)
	}

	return &archivalConfig{
		staticClusterState:    staticClusterState,
		dynamicClusterState:   dynamicClusterState,
		enableRead:            enableRead,
		namespaceDefaultState: namespaceDefaultState,
		namespaceDefaultURI:   namespaceDefaultURI,
	}
}

// NewDisabledArchvialConfig returns an ArchivalConfig where archival is disabled for both the cluster and the namespace
func NewDisabledArchvialConfig() ArchivalConfig {
	return &archivalConfig{
		staticClusterState:    ArchivalDisabled,
		dynamicClusterState:   nil,
		enableRead:            nil,
		namespaceDefaultState: enumspb.ARCHIVAL_STATE_DISABLED,

View on GitHub (pinned to bde624efd1)

Solutions

  1. Correct the namespace default archival state string to a valid value (enabled/disabled/paused)
  2. Inspect the wrapped error for the exact offending value
  3. Add pre-start config validation covering both cluster and namespace archival states
  4. In tests, derive state strings from the package's exported constants instead of literals

Example fix

// before
archivalConfig := archiver.NewArchivalConfig(
    dynamicArchivalStatus, config.StaticArchivalStatus, "defaultEnabled", uri)
// after
archivalConfig := archiver.NewArchivalConfig(
    dynamicArchivalStatus, config.StaticArchivalStatus, "enabled", uri)
Defensive patterns

Strategy: validation

Validate before calling

if !validArchivalState(namespaceDefaultStateStr) {
    return fmt.Errorf("invalid namespace default archival state: %q", namespaceDefaultStateStr)
}

Type guard

func validNamespaceArchivalState(s string) bool {
    switch s {
    case "", "enabled", "disabled", "paused":
        return true
    }
    return false
}

Prevention

When it happens

Trigger: Calling NewArchivalConfig (directly or via NewArchivalMetadata) with a namespaceDefaultURI/state string that getNamespaceArchivalState rejects — i.e. a default namespace archival state string outside the accepted set.

Common situations: Misconfigured namespace default archival state in dynamicconfig or static config (typo like "Enabled"); copy-pasted config between clusters where one uses a different state vocabulary; tests such as TestRegisterNamespace_* passing malformed fixture strings.

Related errors


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