{"record":{"id":"794c3eb57eb759fb","repo":"nexu-io/open-design","slug":"field-contains-unsupported-json-path-segment","errorCode":null,"errorMessage":"${field} contains unsupported JSON path segment: ${segment}","messagePattern":"(.+?) contains unsupported JSON path segment: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"apps/daemon/src/live-artifacts/refresh.ts","lineNumber":287,"sourceCode":"  if (!result.ok) {\n    const firstIssue = result.issues[0];\n    throw new Error(firstIssue === undefined ? result.error : `${firstIssue.path}: ${firstIssue.message}`);\n  }\n  return result.value;\n}\n\nconst SAFE_MAPPING_SEGMENT = /^[A-Za-z_][A-Za-z0-9_-]*$|^(?:0|[1-9][0-9]*)$/;\nconst UNSAFE_MAPPING_SEGMENTS = new Set(['__proto__', 'prototype', 'constructor']);\n\nfunction parseMappingPath(path: string, field: string): string[] {\n  const normalized = path.startsWith('$.') ? path.slice(2) : path;\n  if (normalized.length === 0 || normalized.startsWith('.') || normalized.endsWith('.') || normalized.includes('..')) {\n    throw new Error(`${field} must be a dot-separated JSON path`);\n  }\n  const segments = normalized.split('.');\n  for (const segment of segments) {\n    if (!SAFE_MAPPING_SEGMENT.test(segment) || UNSAFE_MAPPING_SEGMENTS.has(segment)) {\n      throw new Error(`${field} contains unsupported JSON path segment: ${segment}`);\n    }\n  }\n  return segments;\n}\n\nfunction isJsonObject(value: BoundedJsonValue | undefined): value is BoundedJsonObject {\n  return value !== null && typeof value === 'object' && !Array.isArray(value);\n}\n\nfunction readMappedValue(root: BoundedJsonObject, path: string): BoundedJsonValue | undefined {\n  let current: BoundedJsonValue | undefined = root;\n  for (const segment of parseMappingPath(path, 'outputMapping.dataPaths.from')) {\n    if (Array.isArray(current)) {\n      const index = Number(segment);\n      if (!Number.isSafeInteger(index) || index < 0) throw new Error(`outputMapping.dataPaths.from array segment is invalid: ${segment}`);\n      current = current[index];\n    } else if (isJsonObject(current)) {\n      current = current[segment];","sourceCodeStart":269,"sourceCodeEnd":305,"githubUrl":"https://github.com/nexu-io/open-design/blob/5be4028344c2eb4c667c5a97bda8f750c5597ef7/apps/daemon/src/live-artifacts/refresh.ts#L269-L305","documentation":"parseMappingPath (refresh.ts:284-289) checks each dot-separated segment against SAFE_MAPPING_SEGMENT (an identifier `[A-Za-z_][A-Za-z0-9_-]*` or a non-negative integer `0|[1-9][0-9]*`) and rejects prototype-pollution keys (__proto__, prototype, constructor). Any segment that fails either test throws this error.","triggerScenarios":"A dataPath segment contains characters outside the safe set (spaces, brackets, quotes, etc.) or is one of the reserved prototype keys. Example: 'items[0]' (bracket notation), 'a b' (space), or 'foo.__proto__'.","commonSituations":"Using JSONPath/bracket notation instead of dotted notation; copying a path with special characters; an attacker- or user-supplied key that attempts prototype pollution.","solutions":["Convert bracket notation to dotted numeric segments: 'items[0]' -> 'items.0'.","Remove spaces and special characters from path segments; use only letters, digits, underscore, and hyphen.","Never allow user-controlled __proto__/prototype/constructor segments; sanitize inputs upstream."],"exampleFix":"// before\noutputMapping: { dataPaths: [{ from: 'rows[0].name', to: 'result' }] }\n// throws `outputMapping.dataPaths.from contains unsupported JSON path segment: rows[0]`\n\n// after\noutputMapping: { dataPaths: [{ from: 'rows.0.name', to: 'result' }] }","handlingStrategy":"validation","validationCode":"const SAFE = /^[A-Za-z_][A-Za-z0-9_-]*$|^(?:0|[1-9][0-9]*)$/;\nconst FORBIDDEN = new Set(['__proto__', 'prototype', 'constructor']);\nfunction isSafeSegment(seg: string): boolean {\n  return SAFE.test(seg) && !FORBIDDEN.has(seg);\n}\nfunction isSafeDataPath(p: string): boolean {\n  const norm = p.startsWith('$.') ? p.slice(2) : p;\n  return norm.split('.').every(isSafeSegment);\n}","typeGuard":"function isSafeMappingPath(p: unknown): p is string {\n  if (typeof p !== 'string') return false;\n  const norm = p.startsWith('$.') ? p.slice(2) : p;\n  return norm.split('.').every((s) => SAFE.test(s) && !FORBIDDEN.has(s));\n}","tryCatchPattern":null,"preventionTips":["Convert bracket notation to dotted numeric segments before storing paths.","Treat user-supplied path keys as untrusted; filter __proto__/prototype/constructor upstream.","Generate dataPaths from validated segment lists, not raw user strings."],"tags":["live-artifacts","output-mapping","json-path","prototype-pollution","security"],"backgroundTag":null,"analyzedSha":"5be4028344c2eb4c667c5a97bda8f750c5597ef7","analyzedAt":"2026-08-12T12:03:58.812Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}