openclaw/openclaw · error · Error

Invalid Codex runtime invocation descriptor

Error message

Invalid Codex runtime invocation descriptor

What it means

Thrown by validateFilesystemDescriptorShape when descriptor.invocationPaths, after deduping and sorting with compareArtifactNames, does not byte-match the original array. This enforces that invocationPaths is already deduplicated and canonically ordered, which keeps artifact IDs stable and the equal-weight comparison at line 727-728 meaningful.

Source

Thrown at extensions/codex/src/app-server/runtime-artifact.ts:730

    descriptor.managedCommandOrder !== "package-first" &&
    descriptor.managedCommandOrder !== "desktop-first"
  ) {
    throw new Error("Invalid Codex managed command order");
  }
  if (
    descriptor.managedCommandOrder !== undefined &&
    descriptor.commandSource !== "resolved-managed"
  ) {
    throw new Error("Invalid Codex managed runtime descriptor");
  }
  const canonicalInvocationPaths = [...new Set(descriptor.invocationPaths)].toSorted(
    compareArtifactNames,
  );
  if (
    canonicalInvocationPaths.length !== descriptor.invocationPaths.length ||
    canonicalInvocationPaths.some((entry, index) => entry !== descriptor.invocationPaths[index])
  ) {
    throw new Error("Invalid Codex runtime invocation descriptor");
  }
}

function validateArtifactDescriptorShape(descriptor: CodexRuntimeArtifactDescriptor): void {
  validateFilesystemDescriptorShape(descriptor);
  if (
    typeof descriptor.serverVersion !== "string" ||
    descriptor.serverVersion.length === 0 ||
    descriptor.serverVersion.length > 128 ||
    descriptor.serverVersion !== descriptor.serverVersion.trim()
  ) {
    throw new Error("Invalid Codex runtime server version");
  }
  if (
    descriptor.userAgentFingerprint !== undefined &&
    !/^[a-f0-9]{64}$/u.test(descriptor.userAgentFingerprint)
  ) {
    throw new Error("Invalid Codex runtime user-agent fingerprint");

View on GitHub (pinned to 01804a7531)

Solutions

  1. Build invocationPaths via [...new Set(paths)].sort(compareArtifactNames) before assigning.
  2. Ensure commandRealPath is included exactly once (it must be a member, enforced upstream).
  3. Regenerate the descriptor with captureFilesystemDescriptor so canonical ordering is applied.
  4. Keep invocationPaths length within MAX_ARTIFACT_INVOCATION_PATHS (8).

Example fix

// before
invocationPaths: [a, b, a]
// after
invocationPaths: [...new Set([a, b])].sort(compareArtifactNames)
Defensive patterns

Strategy: validation

Validate before calling

function canonicalizeInvocationPaths(paths: string[]): string[] {
  const dedup = [...new Set(paths)].sort(compareArtifactNames);
  if (dedup.length > 8) throw new RangeError("too many invocation paths");
  return dedup;
}

Type guard

function isCanonicalInvocationPaths(paths: unknown): paths is string[] {
  if (!Array.isArray(paths) || paths.length === 0 || paths.length > 8) return false;
  const canon = [...new Set(paths)].sort(compareArtifactNames);
  return canon.length === paths.length && canon.every((p, i) => p === paths[i]) && paths.every((p) => isBoundedPath(p));
}

Prevention

When it happens

Trigger: invocationPaths contains duplicates, is unsorted per compareArtifactNames, or was reordered after capture; the canonical re-sort at line 723-725 diverges from the input and line 726-730 throws.

Common situations: A descriptor was built by concatenating search results without sorting/dedup; cross-platform path separators broke sort order; manual edits reordered entries; a stale descriptor from an older capture format slipped through.

Related errors


AI-assisted analysis of openclaw/openclaw@01804a7531 (2026-08-12). Data as JSON: /api/errors/69209a02d5418484. Report an issue: GitHub.