antonmedv/fx · error
<error from goja Object.Set> (panic(err))
Error message
<error from goja Object.Set> (panic(err))
What it means
After unquoting the key, ToValue calls goja's obj.Set(unquotedKey, value). goja returns an error if the property cannot be set — e.g. a key equal to a non-writable built-in like '__proto__' or a symbol-like/invalid property name on a non-extensible object — and this code panics with that error. It converts a JS-engine property-set failure into a Go panic.
Source
Thrown at internal/jsonx/to_value.go:63
obj := vm.NewObject()
if n.HasChildren() {
it := n
if it.IsCollapsed() {
it = it.Collapsed
} else {
it = it.Next
}
for it != nil && it != n.End {
unquotedKey, err := utils.Unquote(it.Key)
if err != nil {
panic(err)
}
err = obj.Set(unquotedKey, it.ToValue(vm))
if err != nil {
panic(err)
}
if it.HasChildren() {
it = it.End.Next
} else {
it = it.Next
}
}
}
return obj
case Array:
var arr []any
if n.HasChildren() {
it := n
if it.IsCollapsed() {View on GitHub (pinned to 4f31cd3a0c)
Solutions
- Rename or drop the '__proto__' key in the input before conversion.
- Sanitize untrusted JSON: reject or strip dangerous keys like __proto__, constructor, prototype.
- Pre-process the object with a filter that skips un-settable keys, or build the goja object with DefineData/own map instead.
- Recover the panic upstream and report the offending key.
Example fix
// before
{"__proto__": {"admin": true}, "a": 1}
// after
{"prototype": {"admin": true}, "a": 1} // or remove the key entirely Defensive patterns
Strategy: validation
Validate before calling
func hasUnsafeKeys(data []byte) bool {
var m map[string]json.RawMessage
if json.Unmarshal(data, &m) != nil {
return true
}
for k := range m {
if k == "__proto__" || k == "constructor" || k == "prototype" {
return true
}
}
return false
} Try / catch
func safeToValue(n *jsonx.Node, vm *goja.Runtime) (v goja.Value, err error) {
defer func() {
if r := recover(); r != nil {
err = fmt.Errorf("cannot set property on goja object: %v", r)
}
}()
return n.ToValue(vm), nil
} Prevention
- Strip or rename __proto__/constructor/prototype keys from untrusted JSON before conversion.
- Treat prototype-pollution keys as a security signal and reject the document.
- Round-trip through map[string]any with decoder.UseNumber to normalize key sets.
- Wrap ToValue in recover to convert goja Set failures into errors.
When it happens
Trigger: Converting an Object node containing the key '__proto__' (goja rejects setting it directly via Set) or otherwise unwritable property names, during ToValue/KeysComplete.
Common situations: JSON documents crafted with "__proto__" keys (prototype-pollution payloads, e.g. from untrusted web input), or keys colliding with engine internals.
Related errors
- strconv.ParseFloat: parsing <node value>: invalid syntax (pa
- <error from utils.Unquote(n.Value) unquoting the string node
- <error from utils.Unquote(it.Key) unquoting the object key>
- unsupported node kind %d
- Invalid Unicode escape sequence '\u%s%c'
AI-assisted analysis of antonmedv/fx@4f31cd3a0c (2026-09-02).
Data as JSON: /api/errors/b4e110e28c7ac388.
Report an issue: GitHub.