Array of valibot issue records; each may carry a path array.
The value that was validated — used as the root for getPath.
A new array of issues, each augmented with an actual field.
const issues = [
{ path: [{ key: "user" }, { key: "age" }], kind: "schema", message: "Expected number" },
];
const obj = { user: { age: "forty" } };
addActualValueToIssues(issues, obj);
// [
// {
// path: [{ key: "user" }, { key: "age" }],
// kind: "schema",
// message: "Expected number",
// actual: "forty",
// },
// ]
// Missing path → `actual` is undefined
addActualValueToIssues([{ path: [{ key: "missing" }] }], {});
// [{ path: [{ key: "missing" }], actual: undefined }]
export function addActualValueToIssues<T extends PathedIssue>(
issues: readonly T[],
obj: unknown,
): Array<T & { actual: unknown }> {
return issues.map((issue) => ({
...issue,
actual: getPath(obj, (issue.path ?? []).map((segment) => segment.key).filter(isIndexableKey)),
}));
}
Enriches a list of valibot issues (or any
{ path }-shaped records) with the actual value found at each issue's path in the source object. Useful when logging validation failures — stock issues only say "expected X at path Y", and knowing what was there makes debugging drastically faster.The original issue objects are spread shallowly, so extra issue fields (
kind,message,expected, etc.) pass through untouched; only the newactualkey is added. Each path segment'skeyis extracted and non- indexable keys (e.g. a set'snull) are dropped before walking the object.