temporalio/temporal · error

failed to encode chasm path on clean tree: %v

Error message

failed to encode chasm path on clean tree: %v

What it means

During Snapshot's internal walk (snapshotInternal), a node whose LastUpdateVersionedTransition is newer than exclusiveMinVT must be included in the snapshot, which requires encoding the node's tree path. Path encoding should never fail on a clean (fully serialized) tree; if getEncodedPath() returns an error, the tree is in an unexpected state, so the code panics with the error. This is an internal-invariant panic indicating corrupted or inconsistent tree serialization state.

Source

Thrown at chasm/tree.go:2538

	n.snapshotInternal(exclusiveMinVT, nodes)

	return NodesSnapshot{
		Nodes: nodes,
	}
}

func (n *Node) snapshotInternal(
	exclusiveMinVT *persistencespb.VersionedTransition,
	nodes map[string]*persistencespb.ChasmNode,
) {
	if n == nil {
		return
	}

	if transitionhistory.Compare(n.serializedNode.Metadata.LastUpdateVersionedTransition, exclusiveMinVT) > 0 {
		encodedPath, err := n.getEncodedPath()
		if !softassert.That(n.logger, err == nil, "chasm path encoding should always succeed on clean tree") {
			panic(fmt.Sprintf("failed to encode chasm path on clean tree: %v", err))
		}
		nodes[encodedPath] = n.serializedNode
	}

	for _, childNode := range n.children {
		childNode.snapshotInternal(
			exclusiveMinVT,
			nodes,
		)
	}
}

// PartitionedSnapshot returns the tree's state split into two parts:
//   - A NodesSnapshot with cluster-local fields (physical task statuses) zeroed, safe to
//     upload to object storage or replicate to another cluster.
//   - A ChasmLocalState capturing the extracted cluster-local fields, keyed by encoded
//     node path. Only nodes that carry such metadata are present.
//

View on GitHub (pinned to bde624efd1)

Solutions

  1. Treat as a bug report: capture the node/path details from the panic message and file an issue with the workflow execution context
  2. Check for persistence anomalies (missing/partial chasm node rows) for the affected execution
  3. Ensure Snapshot is only called when the tree is committed/clean (per the API contract)
  4. Retry after the tree is next persisted, if the state was transient mid-mutation
Defensive patterns

Strategy: fallback

Try / catch

defer func() {
    if r := recover(); r != nil {
        if s, ok := r.(string); ok && strings.Contains(s, "failed to encode chasm path") {
            // fall back to re-fetching/persisting the tree; report bug
            return
        }
        panic(r)
    }
}()

Prevention

When it happens

Trigger: Calling Node.Snapshot() (on a root, clean tree) where a node's serializedNode exists and its LastUpdateVersionedTransition is > exclusiveMinVT, but getEncodedPath() returns an error — e.g. an empty/invalid path, missing component metadata, or a node not fully serialized.

Common situations: Persistence corruption or a partially written CHASM tree row set; framework bug where a node was mutated without proper serialization before snapshot; snapshotting a tree with nodes in an intermediate/dirty state the IsDirty guard didn't catch.

Related errors


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