AdguardTeam/AdGuardHome · error

client %q is not found

Error message

client %q is not found

What it means

Returned by Storage.Update when no stored client with the given name exists. Update only mutates existing clients; it does not create them.

Source

Thrown at internal/client/storage.go:650

}

// Update finds the stored persistent client by its name and updates its
// information from p.
func (s *Storage) Update(ctx context.Context, name string, p *Persistent) (err error) {
	defer func() { err = errors.Annotate(err, "updating client: %w") }()

	err = p.validate(ctx, s.logger, s.allowedTags)
	if err != nil {
		// Don't wrap the error since there is already an annotation deferred.
		return err
	}

	s.mu.Lock()
	defer s.mu.Unlock()

	stored, ok := s.index.findByName(name)
	if !ok {
		return fmt.Errorf("client %q is not found", name)
	}

	// Client p has a newly generated UID, so replace it with the stored one.
	//
	// TODO(s.chzhen):  Remove when frontend starts handling UIDs.
	p.UID = stored.UID

	err = s.index.clashes(p)
	if err != nil {
		// Don't wrap the error since there is already an annotation deferred.
		return err
	}

	s.index.remove(stored)
	s.index.add(p)

	s.upstreamManager.updateCustomUpstreamConfig(p)

View on GitHub (pinned to b41aefbe51)

Solutions

  1. If the client should exist, re-check its current name with the list/Get API and retry with the correct one
  2. If it was deleted, call Add instead of Update to recreate it
  3. Handle this error explicitly in callers so a missing client triggers Add as a fallback

Example fix

// before
err := s.Update(ctx, "old-name", p) // renamed/deleted

// after
if err := s.Update(ctx, p.Name, p); err != nil {
    if strings.Contains(err.Error(), "is not found") {
        err = s.Add(ctx, p)
    }
}
Defensive patterns

Strategy: fallback

Validate before calling

if _, ok := s.ClientByName(name); !ok { /* client missing; use Add instead */ }

Try / catch

if err := s.Update(ctx, name, p); err != nil {
    if strings.Contains(err.Error(), "is not found") {
        err = s.Add(ctx, p) // upsert fallback
    }
}

Prevention

When it happens

Trigger: Calling Storage.Update(name, p) where name does not match any client in the index (findByName returns false), e.g. the client was deleted, renamed, or never added.

Common situations: Race between a UI edit and a concurrent deletion, renaming a client and updating it under its old name, stale references after a config reload.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


AI-assisted analysis of AdguardTeam/AdGuardHome@b41aefbe51 (2026-08-27). Data as JSON: /api/errors/6ef1065910a9dd31. Report an issue: GitHub.