github/copilot-sdk · error · ResponseError

unsupported_object

unsupported_object

Error message

${context.label} contains a non-JSON array property at ${path}

What it means

Arrays destined for the journal must contain only dense, canonical index properties. If an array has an own property that is not 'length', not a canonical array index string, or an index string whose numeric value is >= the array length (i.e. a non-index property or out-of-range hole), the validator rejects it as a non-JSON array property. This keeps journal data exactly round-trippable through JSON.

Solutions

  1. Inspect the `path` and move the extra property to a wrapper object: { items: [...], total: n }.
  2. Densify sparse arrays before journaling (fill holes with null or use Array.from).
  3. Replace `delete arr[i]` with arr[i] = null to keep the array dense and index-canonical.

Example fix

// before
const items = ["a", "b"];
(items as any).total = 2;
return { items };
// after
return { items: ["a", "b"], total: 2 };
Defensive patterns

Strategy: validation

Validate before calling

function assertDenseArrays(value, path = "$") {
  if (Array.isArray(value)) {
    for (const key of Object.keys(value)) {
      if (key !== "length" && !/^(0|[1-9]\d*)$/.test(key))
        throw new Error(`Non-index property "${key}" on array at ${path}`);
    }
    if (value.length !== Object.keys(value).filter(k => k !== "length").length)
      throw new Error(`Sparse or holey array at ${path}`);
    value.forEach((v, i) => assertDenseArrays(v, `${path}[${i}]`));
  } else if (value && typeof value === "object") {
    for (const [k, v] of Object.entries(value)) assertDenseArrays(v, `${path}.${k}`);
  }
}

Type guard

const isDenseArray = (v: unknown): v is unknown[] =>
  Array.isArray(v) && Object.keys(v).length === v.length;

Try / catch

try {
  session.runFactory(step);
} catch (e) {
  if (e?.details?.category === "unsupported_object" && e.message.includes("array property")) {
    console.error(`Fix extra/sparse array property at ${e.details.path}`);
  } else throw e;
}

Prevention

When it happens

Trigger: Assigning named properties to arrays (arr.foo = 1), creating sparse arrays (arr[10] = 1 with gaps) and then journaling them as factory results/steps, or adding properties beyond arr.length.

Common situations: Tagging arrays with metadata (arr.total = n), sparse arrays from `delete arr[i]` or `new Array(n)` with partial fills, third-party APIs returning arrays with extra fields.

Understand the failure class

Background: "JSON serialization failed", "not JSON serializable", "Failed to serialize": why JSON marshaling errors happen and how to fix them — this error's family across 46 libraries.

Related errors


AI-assisted analysis of github/copilot-sdk@cd8cf15dc3 (2026-09-09). Data as JSON: /api/errors/eb8482049b12d8e2. Report an issue: GitHub.

Appendix: source

Thrown at nodejs/src/session.ts:2373

                path
            );
        }

        ancestors.add(current);
        try {
            if (Array.isArray(current)) {
                const keys = Reflect.ownKeys(current);
                if (
                    keys.length !== current.length + 1 ||
                    keys.some(
                        (key) =>
                            key !== "length" &&
                            (typeof key !== "string" ||
                                !/^(0|[1-9]\d*)$/.test(key) ||
                                Number(key) >= current.length)
                    )
                ) {
                    throw strictJsonValidationError(
                        context,
                        "unsupported_object",
                        `${context.label} contains a non-JSON array property at ${path}`,
                        path
                    );
                }
                for (let index = 0; index < current.length; index++) {
                    const descriptor = Object.getOwnPropertyDescriptor(current, String(index));
                    if (
                        descriptor === undefined ||
                        !descriptor.enumerable ||
                        !("value" in descriptor)
                    ) {
                        throw strictJsonValidationError(
                            context,
                            "unsupported_object",
                            `${context.label} contains a non-JSON array property at ${path}[${index}]`,
                            `${path}[${index}]`

View on GitHub (pinned to cd8cf15dc3)