larksuite/cli · error
segment %q traverses non-object shape
Error message
segment %q traverses non-object shape
What it means
mutateObjectField walks a JSON-pointer path segment by segment to reach the field a DataField override targets. When an intermediate segment names a field whose shape is neither an object nor a oneOf-with-object-variants shape (e.g. a string, array, or scalar), traversal cannot continue and the compiler throws this error. It means the override path descends through a non-object field.
Source
Thrown at shortcuts/common/typed_compile_data.go:400
if len(parts) == 1 {
return mutate(field)
}
switch nested := field.Shape.(type) {
case typedObjectShape:
err := mutateObjectField(&nested, parts[1:], mutate)
field.Shape = nested
return err
case typedOneOfShape:
for variantIndex, variant := range nested.Variants {
if nestedObject, ok := variant.(typedObjectShape); ok {
err := mutateObjectField(&nestedObject, parts[1:], mutate)
nested.Variants[variantIndex] = nestedObject
field.Shape = nested
return err
}
}
}
return fmt.Errorf("segment %q traverses non-object shape", name)
}
return fmt.Errorf("field %q does not exist", name)
}
func pointerFloats(values ...*float64) []float64 {
result := make([]float64, 0, len(values))
for _, value := range values {
if value != nil {
result = append(result, *value)
}
}
return result
}
func shapeHasConstraints(shape typedValueShape) bool {
switch value := shape.(type) {
case typedStringShape:
return len(value.Enum) > 0 || value.Format != "" || value.MinLength != nil || value.MaxLength != nilView on GitHub (pinned to 7fd6ef3c07)
Solutions
- Fix the override Path so every intermediate segment names an object-typed (or oneOf-of-objects) field.
- If the intermediate field is an array, target the array field itself (e.g. "/items") instead of descending into it.
- Update the override after a data-model refactor that turned the nested struct into a scalar or slice.
Example fix
// before
common.TypedDataField{Path: "/owner/name", Description: "Owner"} // owner is a string
// after
common.TypedDataField{Path: "/owner", Description: "Owner name"} Defensive patterns
Strategy: validation
Validate before calling
func pathTraversesObjects(path string, root map[string]common.TypedValueField) error {
parts := strings.Split(strings.TrimPrefix(path, "/"), "/")
cur := root
for _, p := range parts[:len(parts)-1] {
f, ok := cur[p]
if !ok { return fmt.Errorf("missing %q", p) }
obj, ok := f.Shape.(common.TypedObjectShape)
if !ok { return fmt.Errorf("segment %q is not an object", p) }
cur = fieldMap(obj)
}
_, ok := cur[parts[len(parts)-1]]
if !ok { return fmt.Errorf("leaf %q missing", parts[len(parts)-1]) }
return nil
} Type guard
func isObjectShape(s common.TypedValueShape) bool { _, ok := s.(common.TypedObjectShape); return ok } Prevention
- Derive override paths from the actual struct layout, not from memory.
- Remember arrays and scalars cannot be traversed; stop the pointer at the array/scalar field.
- Re-check paths after any nested struct is refactored into a slice or value type.
When it happens
Trigger: CompileCommandDefinition with Output.Data.Overrides[i].Path such as "/items/0/name" or "/tags/inner" where "items" or "tags" is an array, string, number, or other non-object/non-oneOf shape, so a middle pointer segment cannot be traversed.
Common situations: Hand-writing a JSON pointer against the Go data struct and mistaking an array-of-objects for an object; the data model changed a nested struct into a slice or scalar while overrides still used the old deep path.
Related errors
- field %q does not exist
- json.RawMessage requires an explicit Shape
- Shape conflicts with schema constraints
- lark-cli returned a non-object JSON payload
- expected boolean
AI-assisted analysis of larksuite/cli@7fd6ef3c07 (2026-09-04).
Data as JSON: /api/errors/aad9840d549d3399.
Report an issue: GitHub.