antonmedv/fx · error

strconv.ParseFloat: parsing <node value>: invalid syntax (pa

Error message

strconv.ParseFloat: parsing <node value>: invalid syntax (panic(err) on strconv.ParseFloat failure)

What it means

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.

Source

Thrown at internal/jsonx/to_value.go:35

		return goja.Null()

	case Bool:
		if n.Value == "true" {
			return vm.ToValue(true)
		} else {
			return vm.ToValue(false)
		}

	case Number:
		i, ok := ParseNumber(n.Value)
		if ok {
			return vm.ToValue(i)
		}
		f, err := strconv.ParseFloat(n.Value, 64)
		if err == nil {
			return vm.ToValue(f)
		}
		panic(err)

	case String:
		unquoted, err := utils.Unquote(n.Value)
		if err != nil {
			panic(err)
		}
		return vm.ToValue(unquoted)

	case Object:
		obj := vm.NewObject()

		if n.HasChildren() {
			it := n
			if it.IsCollapsed() {
				it = it.Collapsed
			} else {
				it = it.Next
			}

View on GitHub (pinned to 4f31cd3a0c)

Solutions

  1. Check n.Value of the Number node; fix whatever produced the invalid literal.
  2. Re-parse the document instead of reusing/patching Node structures by hand.
  3. Sanitize/validate the numeric text with strconv.ParseFloat yourself before conversion and repair or skip the node.
  4. If it stems from a parser bug, report it with the offending input and recover the panic upstream.

Example fix

// before
n := &jsonx.Node{Kind: jsonx.Number, Value: "1.2.3"}
v := n.ToValue(vm) // panics
// after
n := &jsonx.Node{Kind: jsonx.Number, Value: "1.23"}
v := n.ToValue(vm)
Defensive patterns

Strategy: try-catch

Validate before calling

if _, err := strconv.ParseFloat(node.Value, 64); err != nil {
    return fmt.Errorf("number node %q is not a valid literal", node.Value)
}

Type guard

func isValidNumberNode(n *jsonx.Node) bool {
    if n.Kind != jsonx.Number {
        return false
    }
    _, err := strconv.ParseFloat(n.Value, 64)
    return err == nil
}

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("ToValue failed: %v", r)
        }
    }()
    return n.ToValue(vm), nil
}

Prevention

When it happens

Trigger: 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.

Common situations: Programmatic misuse of the jsonx API (hand-constructed nodes), a parser bug or data corruption, locale-formatted numbers ('1,5') injected into node values.

Related errors


AI-assisted analysis of antonmedv/fx@4f31cd3a0c (2026-09-02). Data as JSON: /api/errors/9d3f739b1f05fd86. Report an issue: GitHub.