larksuite/cli · error
json pointer %q: value at %q is %T, not an object
Error message
json pointer %q: value at %q is %T, not an object
What it means
JSON Pointer traversal in this implementation only descends through objects (map[string]interface{}). If, mid-path, the current value is not an object (a string, number, bool, array, or nil), the traversal cannot continue and reports the Go type found at the traversed prefix.
Source
Thrown at internal/binding/json_pointer.go:44
if !strings.HasPrefix(pointer, "/") {
return nil, fmt.Errorf("json pointer must start with '/' or be empty, got %q", pointer)
}
// Split after the leading "/" and decode each segment.
segments := strings.Split(pointer[1:], "/")
current := data
for i, raw := range segments {
// RFC 6901 unescaping: ~1 → /, ~0 → ~ (order matters).
key, err := decodeJSONPointerSegment(raw)
if err != nil {
return nil, fmt.Errorf("json pointer %q: segment %q: %w", pointer, raw, err)
}
m, ok := current.(map[string]interface{})
if !ok {
traversed := "/" + strings.Join(segments[:i], "/")
return nil, fmt.Errorf("json pointer %q: value at %q is %T, not an object",
pointer, traversed, current)
}
val, exists := m[key]
if !exists {
return nil, fmt.Errorf("json pointer %q: key %q not found", pointer, key)
}
current = val
}
return current, nil
}
func decodeJSONPointerSegment(raw string) (string, error) {
var out strings.Builder
for i := 0; i < len(raw); i++ {
if raw[i] != '~' {View on GitHub (pinned to 7fd6ef3c07)
Solutions
- Shorten the pointer so it stops at an object-valued key
- Inspect the JSON document and align the pointer with the real structure
- Do not use array-index segments — read the containing array value and index in caller code instead
- Re-unmarshal with map[string]interface{} handling if the data isn't a parsed map
Example fix
// before ReadJSONPointer(data, "/accounts/app/id/inner") // id is a string // after ReadJSONPointer(data, "/accounts/app/id")
Defensive patterns
Strategy: type-guard
Validate before calling
v, _ := ReadJSONPointer(data, trimmedPtr) // probe one level above
if _, ok := v.(map[string]interface{}); !ok {
return fmt.Errorf("%q does not resolve to an object", trimmedPtr)
} Type guard
func isObject(v interface{}) bool {
_, ok := v.(map[string]interface{})
return ok
} Try / catch
val, err := binding.ReadJSONPointer(data, ptr)
if err != nil && strings.Contains(err.Error(), "not an object") {
// inspect val type at the parent level; shorten ptr or index arrays manually
} Prevention
- Keep pointers no deeper than the object structure of the document
- Remember arrays are unsupported: index them in caller code after reading
- Re-validate pointers whenever the JSON schema changes
When it happens
Trigger: Pointer like "/accounts/app/id/extra" where "/accounts/app/id" resolves to a string; indexing into an array (arrays are not supported here), or traversing past a scalar.
Common situations: Pointer written deeper than the actual document; trying array index segments ("/channels/0") which this implementation does not support; JSON shape changed (value became a scalar after a bridge upgrade).
Related errors
- json pointer must start with '/' or be empty, got %q
- json pointer %q: segment %q: %w
- json pointer %q: key %q not found
- invalid escape: ~ must be followed by 0 or 1
- invalid escape: ~%c must be ~0 or ~1
AI-assisted analysis of larksuite/cli@7fd6ef3c07 (2026-09-04).
Data as JSON: /api/errors/9c436d11d2b12e94.
Report an issue: GitHub.