t8y2/dbx · error

ETCD_NOT_FOUND

ETCD_NOT_FOUND

Error message

ETCD_NOT_FOUND: source key does not exist

What it means

Not-found error thrown by rename at kv.go:395. After validating newKey, rename GETs the source key; if etcd returns zero kvs, there is nothing to move and the driver returns this error. Unlike get (which returns found:false), rename treats a missing source as a hard failure because the operation cannot proceed.

Source

Thrown at agents/drivers/etcd-go/kv.go:395

		return nil, err
	}
	newKey := stringOrNull(params, "newKey")
	if newKey == nil || *newKey == "" {
		return nil, errors.New("ETCD_NEWKEY_REQUIRED")
	}
	targetKey := *newKey
	if sourceKey == targetKey {
		return map[string]any{"renamed": true, "revision": nil}, nil
	}

	ctx, cancel := s.beginOperation()
	defer s.endOperation(cancel)
	sourceResponse, err := client.Get(ctx, sourceKey)
	if err != nil {
		return nil, err
	}
	if len(sourceResponse.Kvs) == 0 {
		return nil, errors.New("ETCD_NOT_FOUND: source key does not exist")
	}
	source := sourceResponse.Kvs[0]
	expected := longOrNull(params, "expectedModRevision")
	expectedRevision := source.ModRevision
	if expected != nil {
		expectedRevision = *expected
	}
	putOption := []clientv3.OpOption{}
	if source.Lease != 0 {
		putOption = append(putOption, clientv3.WithLease(clientv3.LeaseID(source.Lease)))
	}
	txn := client.Txn(ctx).
		If(
			clientv3.Compare(clientv3.ModRevision(sourceKey), "=", expectedRevision),
			clientv3.Compare(clientv3.CreateRevision(targetKey), "=", 0),
		).
		Then(
			clientv3.OpPut(targetKey, string(source.Value), putOption...),

View on GitHub (pinned to c0390bff16)

Solutions

  1. Check existence first with get(session, sourceKey) and skip/branch when found is false.
  2. Verify the exact key path including prefix and environment namespace (etcdctl get sourceKey).
  3. If the key may have lease-expired, re-create it before renaming or handle the absence explicitly.
  4. Make rename flows idempotent: treat ETCD_NOT_FOUND as 'already renamed' if a prior attempt may have succeeded.

Example fix

// before
rename(session, source, { newKey: dest }); // throws if absent
// after
const cur = get(session, source);
if (!cur.found) return; // nothing to rename
rename(session, source, { newKey: dest });
Defensive patterns

Strategy: validation

Validate before calling

const cur = get(session, sourceKey, { metadataOnly: true });
if (!cur.found) throw new Error(`source key ${sourceKey} does not exist; cannot rename`);

Type guard

function isNotFound(e) { return String(e && e.message || e).includes('ETCD_NOT_FOUND'); }

Try / catch

try { return rename(session, sourceKey, { newKey: destKey }); }
catch (e) {
  if (isNotFound(e)) return { renamed: false, reason: 'source-missing' }; // idempotent handling
  throw e;
}

Prevention

When it happens

Trigger: Calling rename on a sourceKey that does not exist in etcd — never created, already deleted (including lease expiry auto-deletion), or misspelled/differing prefix.

Common situations: Renaming a config key that expired via TTL; race where another worker already renamed/deleted the source; typos or environment-specific key prefixes (/prod vs /staging); case- or slash-sensitivity mismatches in key paths.

Related errors


AI-assisted analysis of t8y2/dbx@c0390bff16 (2026-09-05). Data as JSON: /api/errors/35d5a1f362dc30a5. Report an issue: GitHub.