{"record":{"id":"9d3f739b1f05fd86","repo":"antonmedv/fx","slug":"strconv-parsefloat-parsing-node-value-invalid","errorCode":null,"errorMessage":"strconv.ParseFloat: parsing <node value>: invalid syntax (panic(err) on strconv.ParseFloat failure)","messagePattern":"strconv\\.ParseFloat: parsing <node value>: invalid syntax \\(panic\\(err\\) on strconv\\.ParseFloat failure\\)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/jsonx/to_value.go","lineNumber":35,"sourceCode":"\t\treturn goja.Null()\n\n\tcase Bool:\n\t\tif n.Value == \"true\" {\n\t\t\treturn vm.ToValue(true)\n\t\t} else {\n\t\t\treturn vm.ToValue(false)\n\t\t}\n\n\tcase Number:\n\t\ti, ok := ParseNumber(n.Value)\n\t\tif ok {\n\t\t\treturn vm.ToValue(i)\n\t\t}\n\t\tf, err := strconv.ParseFloat(n.Value, 64)\n\t\tif err == nil {\n\t\t\treturn vm.ToValue(f)\n\t\t}\n\t\tpanic(err)\n\n\tcase String:\n\t\tunquoted, err := utils.Unquote(n.Value)\n\t\tif err != nil {\n\t\t\tpanic(err)\n\t\t}\n\t\treturn vm.ToValue(unquoted)\n\n\tcase Object:\n\t\tobj := vm.NewObject()\n\n\t\tif n.HasChildren() {\n\t\t\tit := n\n\t\t\tif it.IsCollapsed() {\n\t\t\t\tit = it.Collapsed\n\t\t\t} else {\n\t\t\t\tit = it.Next\n\t\t\t}","sourceCodeStart":17,"sourceCodeEnd":53,"githubUrl":"https://github.com/antonmedv/fx/blob/4f31cd3a0c5d66f1b4290a2719bab14a5cee8ebe/internal/jsonx/to_value.go#L17-L53","documentation":"Node.ToValue converts a parsed JSON tree into goja (JavaScript) values. For a Number node it first tries ParseNumber (int64/big.Int); if that fails it falls back to strconv.ParseFloat. If ParseFloat also fails — meaning the number text captured by the parser is not a parseable Go number — the raw error is panicked. Under normal parsing this is unreachable; it indicates a Number node whose Value is corrupted or was constructed outside the parser.","triggerScenarios":"Calling ToValue (e.g. via KeysComplete) on a Number node whose Value is not a valid number literal — such as an empty string, '1.2.3', '0x10', or a node built manually rather than by the parser.","commonSituations":"Programmatic misuse of the jsonx API (hand-constructed nodes), a parser bug or data corruption, locale-formatted numbers ('1,5') injected into node values.","solutions":["Check n.Value of the Number node; fix whatever produced the invalid literal.","Re-parse the document instead of reusing/patching Node structures by hand.","Sanitize/validate the numeric text with strconv.ParseFloat yourself before conversion and repair or skip the node.","If it stems from a parser bug, report it with the offending input and recover the panic upstream."],"exampleFix":"// before\nn := &jsonx.Node{Kind: jsonx.Number, Value: \"1.2.3\"}\nv := n.ToValue(vm) // panics\n// after\nn := &jsonx.Node{Kind: jsonx.Number, Value: \"1.23\"}\nv := n.ToValue(vm)","handlingStrategy":"try-catch","validationCode":"if _, err := strconv.ParseFloat(node.Value, 64); err != nil {\n    return fmt.Errorf(\"number node %q is not a valid literal\", node.Value)\n}","typeGuard":"func isValidNumberNode(n *jsonx.Node) bool {\n    if n.Kind != jsonx.Number {\n        return false\n    }\n    _, err := strconv.ParseFloat(n.Value, 64)\n    return err == nil\n}","tryCatchPattern":"func safeToValue(n *jsonx.Node, vm *goja.Runtime) (v goja.Value, err error) {\n    defer func() {\n        if r := recover(); r != nil {\n            err = fmt.Errorf(\"ToValue failed: %v\", r)\n        }\n    }()\n    return n.ToValue(vm), nil\n}","preventionTips":["Never hand-construct Number nodes; always produce them via the parser.","Validate numeric literals with strconv.ParseFloat before conversion.","Reject locale-formatted numbers (commas, hex) during ingestion.","Keep a recover wrapper around all ToValue calls."],"tags":["json","goja","number","panic","strconv"],"backgroundTag":"invalid-number-literal","analyzedSha":"4f31cd3a0c5d66f1b4290a2719bab14a5cee8ebe","analyzedAt":"2026-09-02T02:17:47.344Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T06:17:21.866Z"}