AdguardTeam/AdGuardHome · error
persistent client at index %d: unexpected type %T
Error message
persistent client at index %d: unexpected type %T
What it means
During migration to schema 22, an element of the persistent clients array is not a YAML object (mapping). Each client must be a map so its "whois"/services field can be restructured; scalars or nested arrays abort the migration.
Source
Thrown at internal/configmigrate/v22.go:53
diskConf["schema_version"] = 22
const field = "blocked_services"
clients, ok, err := fieldVal[yobj](diskConf, "clients")
if !ok {
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",
},
}
}
View on GitHub (pinned to b41aefbe51)
Solutions
- Find the clients array and make every element a mapping (name, ids, etc.)
- Remove malformed client entries that are not real client definitions
- Re-run the migration
Example fix
# before
clients:
- "laptop"
# after
clients:
- name: laptop
ids:
- laptop Defensive patterns
Strategy: type-guard
Validate before calling
for i, c := range clients {
if _, ok := c.(map[string]any); !ok { /* clients[%d] must be a mapping */ _ = i }
} Type guard
func isObj(v any) bool { _, ok := v.(map[string]any); return ok } Try / catch
if err != nil && strings.Contains(err.Error(), "expected object") { /* rewrite offending client entry as a mapping and retry */ } Prevention
- Every list of clients/filters should be a list of mappings, never scalars
When it happens
Trigger: Migrating a config whose clients list contains a string, number, or array element instead of a mapping, e.g. `clients: [ "laptop" ]`.
Common situations: Hand-rolled configs where a client was written as a plain name, or list-vs-map confusion after editing the YAML.
Related errors
- unexpected type of upstream field: %T
- persistent client at index %d: %w
- filters: at index %d: expected object, got %T
- unexpected type of %q: %T
- parsing config file for upgrade: %w
AI-assisted analysis of AdguardTeam/AdGuardHome@b41aefbe51 (2026-08-27).
Data as JSON: /api/errors/8adf76623ee4df66.
Report an issue: GitHub.