{"record":{"id":"960207f1ce3c6f55","repo":"antonmedv/fx","slug":"error-from-utils-unquote-n-value-unquoting-the-s","errorCode":null,"errorMessage":"<error from utils.Unquote(n.Value) unquoting the string node> (panic(err))","messagePattern":"<error from utils\\.Unquote\\(n\\.Value\\) unquoting the string node> \\(panic\\(err\\)\\)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/jsonx/to_value.go","lineNumber":40,"sourceCode":"\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}\n\n\t\t\tfor it != nil && it != n.End {\n\t\t\t\tunquotedKey, err := utils.Unquote(it.Key)\n\t\t\t\tif err != nil {\n\t\t\t\t\tpanic(err)","sourceCodeStart":22,"sourceCodeEnd":58,"githubUrl":"https://github.com/antonmedv/fx/blob/4f31cd3a0c5d66f1b4290a2719bab14a5cee8ebe/internal/jsonx/to_value.go#L22-L58","documentation":"For String nodes, ToValue calls utils.Unquote to turn the raw token text (including quotes and escape sequences) into the unquoted Go string. If Unquote fails — the token contains an invalid escape sequence or malformed quoting — the error is panicked. This means a String node holds text that is not a well-formed JSON string literal.","triggerScenarios":"ToValue on a String node whose Value has bad escapes (e.g. '\\x41', lone backslash, raw control characters) or is missing/malformed surrounding quotes — typically from hand-built nodes or corrupted input.","commonSituations":"Windows paths with single backslashes pasted into JSON (\"C:\\Users\\x\"), hand-constructed nodes in tests, files edited with tools that mangle escapes.","solutions":["Fix the string literal so all backslashes are properly escaped (\\\\) and quotes/escapes are JSON-valid.","Re-parse the source document rather than constructing String nodes manually.","Validate with a JSON linter before parsing; escape backslashes programmatically when generating input.","Recover the panic and surface it with the node's line number for debugging."],"exampleFix":"// before\n{\"path\": \"C:\\Users\\x\"}\n// after\n{\"path\": \"C:\\\\Users\\\\x\"}","handlingStrategy":"type-guard","validationCode":"var s string\nif err := json.Unmarshal([]byte(n.Value), &s); err != nil {\n    return fmt.Errorf(\"string node %q is not a valid JSON string\", n.Value)\n}","typeGuard":"func isValidStringNode(n *jsonx.Node) bool {\n    if n.Kind != jsonx.String {\n        return false\n    }\n    var s string\n    return json.Unmarshal([]byte(n.Value), &s) == 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 on string node: %v\", r)\n        }\n    }()\n    return n.ToValue(vm), nil\n}","preventionTips":["Escape backslashes when generating JSON on Windows paths.","Generate JSON with an encoder (json.Marshal), never string concatenation.","Round-trip validate strings with encoding/json before feeding to jsonx.","Avoid constructing String nodes manually in tests."],"tags":["json","string","unquote","escape","panic"],"backgroundTag":"invalid-escape-sequence","analyzedSha":"4f31cd3a0c5d66f1b4290a2719bab14a5cee8ebe","analyzedAt":"2026-09-02T02:17:47.344Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T06:17:21.866Z"}