Lossless JSON Parsing (parseJsonPrioritised)#
parseJsonPrioritised() is a precision-safe JSON parser in the shared utilities package (packages/shared/src/utils/json.ts). It solves a specific problem: JavaScript's native JSON.parse silently rounds integers outside the IEEE 754 safe-integer range (±2⁵³), which corrupts large numeric IDs and timestamps common in LLM traces, dataset items, and evaluation metadata.
How It Works#
The function uses a two-path strategy :
-
Fast path — if the input string contains no sequence of 13+ digit/dot characters and no scientific notation (regex
UNSAFE_NUMBER_PATTERN = /[\d.]{13,}|\d[eE]/), it delegates directly to nativeJSON.parse. This keeps the common case cheap. -
Slow path — if potentially unsafe numbers are detected, it invokes
parse()fromlossless-jsonwith a custom number reviver:- Numbers passing
isSafeNumber()are converted to JSNumber(normal behavior). - Numbers failing
isSafeNumber()are preserved as their string representation (e.g.,"107505301260286111"), preventing silent rounding.
- Numbers passing
Parse errors are caught and the original string is returned as a fallback .
Where It's Used#
| Location | Purpose |
|---|---|
packages/shared/src/server/utils/rendering.ts | Parses input/output fields in API responses |
packages/shared/src/server/utils/metadata_conversion.ts | Converts ClickHouse array-column metadata into domain objects |
packages/shared/src/features/batchAction/applyFieldMapping.ts | Pre-parses data before JSONPath extraction in dataset field mapping |
packages/shared/src/server/services/DatasetService/DatasetItemValidator.ts | Normalizes input, expectedOutput, and metadata on dataset item creation/update |
packages/shared/src/features/evals/utilities.ts | Parses multi-encoded JSON in eval pipelines (parseMultiEncodedJson) |
worker/src/features/tokenisation/usage.ts | Parses chat messages stored as strings in ClickHouse for token counting |
worker/src/scripts/verifyClickhouseRecords/index.ts | Parses fields when comparing PostgreSQL vs. ClickHouse for data consistency |
web/src/features/datasets/components/NewDatasetItemFromExistingObject.tsx | Normalizes prefill values when creating dataset items from existing objects |
The function is exported from the shared package index and consumed by backend workers, the API server, and the web frontend.
Key Design Decisions#
- Strings, not BigInt — unsafe integers are kept as strings rather than
bigintbecause the rest of the pipeline (ClickHouse, LLM prompts, Lambda/runtime boundaries, JSON serialization) is JSON-based.bigintwould not survive re-serialization . - Regex pre-screening — the
UNSAFE_NUMBER_PATTERNcheck avoids invoking the slowerlossless-jsonparser on the majority of payloads that contain only safe numbers . - Context: eval precision fix — PR #14119 extended
parseJsonPrioritisedusage to the full eval/dataset pipeline after discovering thatJSON.parsewas corrupting large dataset integer IDs (e.g.,107505301260286111) before they reached LLM prompts.
Related Utilities in the Same File#
deepParseJson/deepParseJsonIterative— recursively unwrap nested stringified JSON up to configurable depth and size limits. These use nativeJSON.parseinternally (not lossless), so they are suited for UI rendering rather than precision-sensitive ingestion.tryParsePythonDict— converts Python dict/list syntax (e.g., LangChain/LangGraph tool calls) to valid JSON before parsing.