{"record":{"id":"55de1d9c5661c992","repo":"nexu-io/open-design","slug":"outputmapping-datapaths-from-array-segment-is-inva","errorCode":null,"errorMessage":"outputMapping.dataPaths.from array segment is invalid: ${segment}","messagePattern":"outputMapping\\.dataPaths\\.from array segment is invalid: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"apps/daemon/src/live-artifacts/refresh.ts","lineNumber":302,"sourceCode":"  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];\n    } else {\n      return undefined;\n    }\n    if (current === undefined) return undefined;\n  }\n  return current;\n}\n\nfunction makeContainer(nextSegment: string): BoundedJsonObject | BoundedJsonValue[] {\n  return /^(?:0|[1-9][0-9]*)$/.test(nextSegment) ? [] : {};\n}\n\nfunction writeMappedValue(root: BoundedJsonObject, path: string, value: BoundedJsonValue): void {\n  const segments = parseMappingPath(path, 'outputMapping.dataPaths.to');\n  let current: BoundedJsonObject | BoundedJsonValue[] = root;","sourceCodeStart":284,"sourceCodeEnd":320,"githubUrl":"https://github.com/nexu-io/open-design/blob/5be4028344c2eb4c667c5a97bda8f750c5597ef7/apps/daemon/src/live-artifacts/refresh.ts#L284-L320","documentation":"readMappedValue (refresh.ts:297-312) walks the source object along a dataPaths.from path. When the current node is an array, the next segment must be a valid non-negative integer index; if Number(segment) is not a safe non-negative integer, this throws. This catches a path that descends into an array using a non-numeric key.","triggerScenarios":"A dataPaths.from path reaches an array node but the next segment is non-numeric, e.g. source has `items: [...]` and the path is 'items.name' (expecting an object but finding an array).","commonSituations":"The connector/daemon output shape differs from what the mapping assumed (array where an object was expected); a mapping written against an older output schema; an array index segment written as a non-numeric label.","solutions":["Use a numeric segment to index into arrays, e.g. 'items.0.name' instead of 'items.name'.","Verify the actual output shape and align the dataPath to it (object vs array).","If the field may be an array or object, normalize the source output before mapping."],"exampleFix":"// before: output is { items: [{ name: 'x' }] } but path treats items as object\noutputMapping: { dataPaths: [{ from: 'items.name', to: 'name' }] }\n// throws `outputMapping.dataPaths.from array segment is invalid: name`\n\n// after: index the array\noutputMapping: { dataPaths: [{ from: 'items.0.name', to: 'name' }] }","handlingStrategy":"validation","validationCode":"function fromPathMatchesOutput(path: string, sample: unknown): boolean {\n  let cur: unknown = sample;\n  for (const seg of (path.startsWith('$.') ? path.slice(2) : path).split('.')) {\n    if (Array.isArray(cur)) {\n      const i = Number(seg);\n      if (!Number.isSafeInteger(i) || i < 0) return false;\n      cur = cur[i];\n    } else if (cur && typeof cur === 'object') {\n      cur = (cur as Record<string, unknown>)[seg];\n    } else return true;\n    if (cur === undefined) return true;\n  }\n  return true;\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Verify the actual output shape (object vs array) before writing the dataPath.","Use numeric segments ('items.0.name') to index arrays in from-paths.","Snapshot a sample connector/daemon output and dry-run the mapping against it."],"tags":["live-artifacts","output-mapping","json-path","array"],"backgroundTag":null,"analyzedSha":"5be4028344c2eb4c667c5a97bda8f750c5597ef7","analyzedAt":"2026-08-12T12:03:58.812Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}