larksuite/cli · error
json pointer must start with '/' or be empty, got %q
Error message
json pointer must start with '/' or be empty, got %q
What it means
ReadJSONPointer implements RFC 6901 JSON Pointer traversal over a parsed JSON value. Per the spec, a pointer must be either the empty string (returns the whole document) or start with '/'. This error rejects any non-empty pointer lacking the leading slash before any traversal happens.
Source
Thrown at internal/binding/json_pointer.go:27
)
// ReadJSONPointer navigates a parsed JSON value (typically the result of
// json.Unmarshal into interface{}) using an RFC 6901 JSON Pointer string.
//
// Supported pointer format: "/key/subkey/subsubkey".
// An empty pointer ("") returns data as-is.
// RFC 6901 escape sequences: ~1 → /, ~0 → ~.
//
// Limitation: only object (map) traversal is supported. Array index segments
// (e.g., "/channels/0/appId") are not implemented because OpenClaw's
// SecretRef file provider uses object-only paths in practice.
func ReadJSONPointer(data interface{}, pointer string) (interface{}, error) {
if pointer == "" {
return data, nil
}
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)View on GitHub (pinned to 7fd6ef3c07)
Solutions
- Prefix the pointer with '/': "accounts/app/id" not "accounts.app.id"
- Use the empty string "" when you want the entire document
- Trim whitespace and convert dot-separated paths to slash-separated segments
Example fix
// before ReadJSONPointer(data, "accounts.app.id") // after ReadJSONPointer(data, "/accounts/app/id")
Defensive patterns
Strategy: validation
Validate before calling
func validPointer(p string) bool { return p == "" || strings.HasPrefix(p, "/") }
if !validPointer(ptr) {
ptr = "/" + strings.ReplaceAll(strings.TrimLeft(ptr, "."), ".", "/")
} Prevention
- Always write JSON Pointers in RFC 6901 form with a leading '/'
- Convert dot-notation paths to slash-separated form at config-load time
- Trim whitespace before passing the pointer
When it happens
Trigger: Calling ReadJSONPointer(data, "key") or "a.b" — any pointer that is neither "" nor starts with '/'.
Common situations: Users writing dot-notation ("accounts.app.id") or bare key names in a SecretRef path; config values copied from JSONPath; whitespace before the slash.
Related errors
- malformed config
- app registration failed: response missing device_code
- json pointer %q: segment %q: %w
- json pointer %q: value at %q is %T, not an object
- json pointer %q: key %q not found
AI-assisted analysis of larksuite/cli@7fd6ef3c07 (2026-09-04).
Data as JSON: /api/errors/efa694a1f4213ad2.
Report an issue: GitHub.