AdguardTeam/AdGuardHome · error
persistent client at index %d: %w
Error message
persistent client at index %d: %w
What it means
During migration to schema 22, extracting the services field from a persistent client object failed (fieldVal error), wrapped with the client's index. Typically the field exists but has the wrong type (e.g. whois is a string where an array is expected).
Source
Thrown at internal/configmigrate/v22.go:59
return err
}
persistent, ok, err := fieldVal[yarr](clients, "persistent")
if !ok {
return err
}
for i, p := range persistent {
var c yobj
c, ok = p.(yobj)
if !ok {
return fmt.Errorf("persistent client at index %d: unexpected type %T", i, p)
}
var services yarr
services, ok, err = fieldVal[yarr](c, field)
if err != nil {
return fmt.Errorf("persistent client at index %d: %w", i, err)
} else if !ok {
continue
}
c[field] = yobj{
"ids": services,
"schedule": yobj{
"time_zone": "Local",
},
}
}
return nil
}
View on GitHub (pinned to b41aefbe51)
Solutions
- Check the client at the index in the message; make its whois field either absent or a list
- Set `whois: []` if you just need a syntactically valid empty value
- Retry Migrate
Example fix
# before
- name: laptop
whois: "example.com"
# after
- name: laptop
whois:
- example.com Defensive patterns
Strategy: type-guard
Validate before calling
for _, c := range clients {
obj, ok := c.(map[string]any)
if !ok { continue }
if w, ok := obj["whois"]; ok {
if _, ok := w.([]any); !ok { /* whois must be a list or removed */ }
}
} Type guard
func isStringArray(v any) bool { _, ok := v.([]any); if !ok { return false }; for _, e := range v.([]any) { if _, ok := e.(string); !ok { return false } }; return true } Try / catch
if err != nil && strings.Contains(err.Error(), "persistent client at index") { /* check client at that index, coerce whois to a list, retry */ } Prevention
- Keep whois/services fields as lists of strings
When it happens
Trigger: Migrating a config where a client's whois/services field is present but not an array (yarr), e.g. `whois: true` or `whois: "example.com"`.
Common situations: Hand-edited clients where the whois field was replaced by a scalar; older or third-party tooling writing the field with the wrong shape.
Related errors
- persistent client at index %d: unexpected type %T
- unexpected type of upstream field: %T
- filters: at index %d: expected object, got %T
- unexpected type of %q: %T
- invalid upstream servers: %w
AI-assisted analysis of AdguardTeam/AdGuardHome@b41aefbe51 (2026-08-27).
Data as JSON: /api/errors/6e67abd865721697.
Report an issue: GitHub.