pocketbase/pocketbase · error
expected map or array, got %#v
Error message
expected map or array, got %#v
What it means
extractNestedVal walked a key path into a JSON value whose current node is neither a map nor an array (e.g. a string or number), so the remaining path segments cannot be applied. The message prints the offending value with %#v, showing exactly what was found instead.
Source
Thrown at core/record_field_resolver.go:540
return arrVal(m, keys...)
case []uint16:
return arrVal(m, keys...)
case []uint32:
return arrVal(m, keys...)
case []uint64:
return arrVal(m, keys...)
case []mapExtractor:
extracted := make([]any, len(m))
for i, v := range m {
extracted[i] = v.AsMap()
}
return arrVal(extracted, keys...)
case []any:
return arrVal(m, keys...)
case []types.JSONRaw:
return arrVal(m, keys...)
default:
return nil, fmt.Errorf("expected map or array, got %#v", rawData)
}
}
func mapVal[T any](m map[string]T, keys ...string) (any, error) {
result, ok := m[keys[0]]
if !ok {
return nil, fmt.Errorf("invalid key path - missing key %q", keys[0])
}
// end key reached
if len(keys) == 1 {
return result, nil
}
return extractNestedVal(result, keys[1:]...)
}
func arrVal[T any](m []T, keys ...string) (any, error) {View on GitHub (pinned to 5d217ddb50)
Solutions
- Inspect the printed value — it tells you the actual type at that path; adjust the filter path to match the real structure.
- Normalize the stored data so the path has a consistent shape in every row (migration over the json column).
- Guard heterogeneous fields by first filtering on a stable part (e.g. type discriminator) before the nested path.
Example fix
// before: tags sometimes stored as string filter := "meta.tags.name = 'x'" // after: normalize data so tags is always an array of objects, then keep the filter
Defensive patterns
Strategy: type-guard
Type guard
func isMapOrArray(v any) bool {
switch v.(type) {
case map[string]any, []any:
return true
}
return false
} Try / catch
if err != nil && strings.Contains(err.Error(), "expected map or array") {
// the %#v in the message shows the actual value — align the filter path with the real shape
} Prevention
- Keep json field shapes uniform across rows (schema discipline inside json).
- Test filters against a representative sample of rows, not one record.
- Prefer typed top-level fields for anything you filter on regularly.
When it happens
Trigger: Filter like "meta.tags.name = 'x'" where meta.tags is a plain string in some rows (not an array of objects), or "settings.theme.dark = true" where settings.theme is the boolean true.
Common situations: Heterogeneous json field content across rows (some rows store a scalar where others store an object); schema evolved inside a schemaless json field; filter authored against an example row that is not representative.
Related errors
- failed to unmarshal raw JSON in order extract nested value f
- invalid key path - missing key %q
- invalid key path - invalid or missing array index %q
- cannot serialize the data for field %q
- Invalid realtime client.
AI-assisted analysis of pocketbase/pocketbase@5d217ddb50 (2026-08-15).
Data as JSON: /api/errors/c5ed81117aae6861.
Report an issue: GitHub.