larksuite/cli · info
marshal key %q: %w
Error message
marshal key %q: %w
What it means
OrderedMap.MarshalJSON serializes the map while preserving insertion order by marshaling each key separately. This error wraps a failure from json.Marshal on an individual key. In practice keys are Go strings, which always marshal successfully, so this is a defensive guard that should virtually never fire.
Source
Thrown at internal/schema/types.go:133
return []byte("{}"), nil
}
keys := o.Order
if len(keys) == 0 {
keys = make([]string, 0, len(o.Map))
for k := range o.Map {
keys = append(keys, k)
}
sort.Strings(keys)
}
var buf bytes.Buffer
buf.WriteByte('{')
for i, k := range keys {
if i > 0 {
buf.WriteByte(',')
}
keyJSON, err := json.Marshal(k)
if err != nil {
return nil, fmt.Errorf("marshal key %q: %w", k, err)
}
buf.Write(keyJSON)
buf.WriteByte(':')
valJSON, err := json.Marshal(o.Map[k])
if err != nil {
return nil, fmt.Errorf("marshal value for %q: %w", k, err)
}
buf.Write(valJSON)
}
buf.WriteByte('}')
return buf.Bytes(), nil
}
// UnmarshalJSON parses an object preserving key order via json.Decoder.Token().
// Used for round-tripping in tests (and future golden update flows).
func (o *OrderedProps) UnmarshalJSON(data []byte) error {
dec := json.NewDecoder(bytes.NewReader(data))
tok, err := dec.Token()View on GitHub (pinned to 7fd6ef3c07)
Solutions
- Inspect the wrapped %w cause to identify the unmarshalable key value
- Confirm keys are plain strings; strings are always JSON-marshalable
- If you changed the key type, add a MarshalJSON method to the key type or convert keys to string before insertion
Example fix
// before (custom key type that fails to marshal)
type Key struct{ ID chan int }
// after
type Key struct{ ID string }
func (k Key) MarshalJSON() ([]byte, error) { return json.Marshal(k.ID) } Defensive patterns
Strategy: try-catch
Try / catch
data, err := json.Marshal(om)
if err != nil {
var mErr *fmt.wrapError
if errors.As(err, &mErr) && strings.Contains(err.Error(), "marshal key") {
// fix key type in OrderedMap
}
return err
} Prevention
- Keep OrderedMap keys as plain strings
- Add marshal round-trip tests for OrderedMap
- If changing key type, give it a working MarshalJSON
When it happens
Trigger: Calling json.Marshal (or any encoding that invokes MarshalJSON) on an internal/schema OrderedMap whose key cannot be JSON-encoded. With the current string-typed keys this is unreachable; it would only fire if the key type changed to a non-JSON-serializable type (e.g. chan, func, or a type with a failing MarshalJSON).
Common situations: Developers encounter this only via the wrapped cause in a larger marshal failure chain, typically while debugging custom schema property maps after modifying the OrderedMap key type.
Understand the failure class
Background: json.Marshal / "failed to marshal" errors in Go: why "unsupported type" happens and how to fix it — this error's family across 22 libraries.
Related errors
- marshal value for %q: %w
- lark-cli returned a non-object JSON payload
- protocol encode: %w
- parse base schema for field overrides: %w
- serialize schema with field overrides: %w
AI-assisted analysis of larksuite/cli@7fd6ef3c07 (2026-09-04).
Data as JSON: /api/errors/5cf6d2e1e2885db1.
Report an issue: GitHub.