AdguardTeam/AdGuardHome · error
filters: at index %d: expected object, got %T
Error message
filters: at index %d: expected object, got %T
What it means
During migration to schema 29, an element of the filters array is not a YAML object. Each filter must be a mapping so its url field can be inspected (and rewritten if it's an absolute local path); scalars or nested arrays abort the migration.
Source
Thrown at internal/configmigrate/v29.go:46
// - '/path/to/file.txt'
// # …
func (m Migrator) migrateTo29(_ context.Context, diskConf yobj) (err error) {
diskConf["schema_version"] = 29
filterVals, ok, err := fieldVal[[]any](diskConf, "filters")
if !ok {
return err
}
paths := []string{
filepath.Join(m.dataDir, "userfilters", "*"),
}
for i, v := range filterVals {
var f yobj
f, ok = v.(yobj)
if !ok {
return fmt.Errorf("filters: at index %d: expected object, got %T", i, v)
}
var u string
u, ok, _ = fieldVal[string](f, "url")
if ok && filepath.IsAbs(u) {
paths = append(paths, u)
}
}
fltConf, ok, err := fieldVal[yobj](diskConf, "filtering")
if !ok {
return err
}
fltConf["safe_fs_patterns"] = paths
return nil
}View on GitHub (pinned to b41aefbe51)
Solutions
- Rewrite every filters entry as a mapping with url/enabled keys
- Delete malformed entries that aren't real filter definitions
- Re-run Migrate
Example fix
# before
filters:
- https://example.org/hosts
# after
filters:
- enabled: true
url: https://example.org/hosts Defensive patterns
Strategy: type-guard
Validate before calling
for _, f := range filters {
if _, ok := f.(map[string]any); !ok { /* rewrite as {url: ..., enabled: true} */ }
} Type guard
func isFilterObj(v any) bool { _, ok := v.(map[string]any); return ok } Try / catch
if err != nil && strings.Contains(err.Error(), "expected object, got") { /* convert bare-string filters to objects and retry */ } Prevention
- Each filter entry needs url and enabled keys
When it happens
Trigger: Migrating a config where filters contains a non-object entry, e.g. `- https://example.org/hosts` (bare string) instead of `- url: https://example.org/hosts, enabled: true`.
Common situations: Hand-converted configs where filter URLs were written as plain list items; merging filter lists from different sources with inconsistent shapes.
Related errors
- unexpected type of upstream field: %T
- persistent client at index %d: unexpected type %T
- unexpected type of %q: %T
- parsing config file for upgrade: %w
- generating new config: %w
AI-assisted analysis of AdguardTeam/AdGuardHome@b41aefbe51 (2026-08-27).
Data as JSON: /api/errors/1bc71f88617cd8cd.
Report an issue: GitHub.