decolua/9router · error · Error

transform returned an unexpected shape

Error message

transform returned an unexpected shape

What it means

Thrown by selfTest after invoking the loaded pxpipe transformAnthropicMessages on a tiny synthetic Claude request. The transform is required to return an object with `applied` (boolean) and `body` (Uint8Array); anything else means the module loaded and exposed the function but violated its output contract, so the health check fails rather than passing malformed data downstream.

Source

Thrown at src/lib/pxpipe/loader.js:67

    return mod.transformAnthropicMessages;
  } catch {
    return null;
  }
}

// Health self-test: run a tiny synthetic Claude request through the transformer.
// A healthy module parses it and answers with a machine-readable reason.
export async function selfTest() {
  const startedAt = Date.now();
  const { module: mod } = await loadPxpipe();
  const body = new TextEncoder().encode(JSON.stringify({
    model: "claude-fable-5",
    max_tokens: 16,
    messages: [{ role: "user", content: "ping" }],
  }));
  const result = await mod.transformAnthropicMessages({ body, model: "claude-fable-5" });
  if (!result || typeof result.applied !== "boolean" || !(result.body instanceof Uint8Array)) {
    throw new Error("transform returned an unexpected shape");
  }
  return { ok: true, reason: result.reason, durationMs: Date.now() - startedAt };
}

View on GitHub (pinned to 90b52e06ff)

Solutions

  1. Log the actual return value of transformAnthropicMessages in selfTest to see what shape came back, then compare with the expected {applied: boolean, body: Uint8Array, reason} contract.
  2. Upgrade or downgrade pxpipe to the version matching this app's contract (use Repair, which cache-busts via ?v=version).
  3. Fix the pxpipe transform to always return {applied, body: Uint8Array, reason} — e.g. wrap Buffer results: new Uint8Array(buffer).
  4. Ensure the transform re-encodes the body even when nothing is applied (applied:false path must still return a Uint8Array body).
  5. Rebuild the pxpipe module if a local patch or bundler step altered the return type, then re-run the self-test.

Example fix

// before (pxpipe transform returning Buffer)
return { applied: changed, body: Buffer.from(out), reason };
// after
return { applied: changed, body: new Uint8Array(out), reason };
Defensive patterns

Strategy: type-guard

Validate before calling

const result = await transform({ body, model });
if (!result || typeof result.applied !== "boolean" || !(result.body instanceof Uint8Array)) {
  throw new Error("transform returned an unexpected shape");
}

Type guard

function isTransformResult(r) {
  return !!r && typeof r.applied === "boolean" && r.body instanceof Uint8Array;
}
// tolerate Buffer under Node:
const ok = isTransformResult(r) || (r && typeof r.applied === "boolean" && Buffer.isBuffer(r.body));

Try / catch

try {
  const report = await selfTest();
} catch (e) {
  if (e.message === "transform returned an unexpected shape") {
    console.error("pxpipe contract violation — reinstall matching version or fix transform return to {applied:boolean, body:Uint8Array}");
  } else throw e;
}

Prevention

When it happens

Trigger: transformAnthropicMessages returns null/undefined (e.g. it failed internally and returned nothing), returns a plain object missing `applied`, or returns body as a Buffer/string/ArrayBuffer instead of a Uint8Array — detected only when selfTest (the Test button / health probe) runs.

Common situations: A pxpipe version bump changed the return shape (e.g. returning Buffer, or {ok, data} instead of {applied, body, reason}); the transform swallows an error and returns undefined; a hand-patched/local build of pxpipe diverging from the documented contract; running selfTest against a module built for a different runtime (returning ArrayBuffer under Node).

Related errors


AI-assisted analysis of decolua/9router@90b52e06ff (2026-08-30). Data as JSON: /api/errors/00509940423e9067. Report an issue: GitHub.