nexu-io/open-design · error

outputMapping.dataPaths.from array segment is invalid: ${seg

Error message

outputMapping.dataPaths.from array segment is invalid: ${segment}

What it means

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.

Source

Thrown at apps/daemon/src/live-artifacts/refresh.ts:302

  const segments = normalized.split('.');
  for (const segment of segments) {
    if (!SAFE_MAPPING_SEGMENT.test(segment) || UNSAFE_MAPPING_SEGMENTS.has(segment)) {
      throw new Error(`${field} contains unsupported JSON path segment: ${segment}`);
    }
  }
  return segments;
}

function isJsonObject(value: BoundedJsonValue | undefined): value is BoundedJsonObject {
  return value !== null && typeof value === 'object' && !Array.isArray(value);
}

function readMappedValue(root: BoundedJsonObject, path: string): BoundedJsonValue | undefined {
  let current: BoundedJsonValue | undefined = root;
  for (const segment of parseMappingPath(path, 'outputMapping.dataPaths.from')) {
    if (Array.isArray(current)) {
      const index = Number(segment);
      if (!Number.isSafeInteger(index) || index < 0) throw new Error(`outputMapping.dataPaths.from array segment is invalid: ${segment}`);
      current = current[index];
    } else if (isJsonObject(current)) {
      current = current[segment];
    } else {
      return undefined;
    }
    if (current === undefined) return undefined;
  }
  return current;
}

function makeContainer(nextSegment: string): BoundedJsonObject | BoundedJsonValue[] {
  return /^(?:0|[1-9][0-9]*)$/.test(nextSegment) ? [] : {};
}

function writeMappedValue(root: BoundedJsonObject, path: string, value: BoundedJsonValue): void {
  const segments = parseMappingPath(path, 'outputMapping.dataPaths.to');
  let current: BoundedJsonObject | BoundedJsonValue[] = root;

View on GitHub (pinned to 5be4028344)

Solutions

  1. Use a numeric segment to index into arrays, e.g. 'items.0.name' instead of 'items.name'.
  2. Verify the actual output shape and align the dataPath to it (object vs array).
  3. If the field may be an array or object, normalize the source output before mapping.

Example fix

// before: output is { items: [{ name: 'x' }] } but path treats items as object
outputMapping: { dataPaths: [{ from: 'items.name', to: 'name' }] }
// throws `outputMapping.dataPaths.from array segment is invalid: name`

// after: index the array
outputMapping: { dataPaths: [{ from: 'items.0.name', to: 'name' }] }
Defensive patterns

Strategy: validation

Validate before calling

function fromPathMatchesOutput(path: string, sample: unknown): boolean {
  let cur: unknown = sample;
  for (const seg of (path.startsWith('$.') ? path.slice(2) : path).split('.')) {
    if (Array.isArray(cur)) {
      const i = Number(seg);
      if (!Number.isSafeInteger(i) || i < 0) return false;
      cur = cur[i];
    } else if (cur && typeof cur === 'object') {
      cur = (cur as Record<string, unknown>)[seg];
    } else return true;
    if (cur === undefined) return true;
  }
  return true;
}

Prevention

When it happens

Trigger: 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).

Common situations: 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.

Related errors


AI-assisted analysis of nexu-io/open-design@5be4028344 (2026-08-12). Data as JSON: /api/errors/55de1d9c5661c992. Report an issue: GitHub.