{"record":{"id":"69209a02d5418484","repo":"openclaw/openclaw","slug":"invalid-codex-runtime-invocation-descriptor","errorCode":null,"errorMessage":"Invalid Codex runtime invocation descriptor","messagePattern":"Invalid Codex runtime invocation descriptor","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"extensions/codex/src/app-server/runtime-artifact.ts","lineNumber":730,"sourceCode":"    descriptor.managedCommandOrder !== \"package-first\" &&\n    descriptor.managedCommandOrder !== \"desktop-first\"\n  ) {\n    throw new Error(\"Invalid Codex managed command order\");\n  }\n  if (\n    descriptor.managedCommandOrder !== undefined &&\n    descriptor.commandSource !== \"resolved-managed\"\n  ) {\n    throw new Error(\"Invalid Codex managed runtime descriptor\");\n  }\n  const canonicalInvocationPaths = [...new Set(descriptor.invocationPaths)].toSorted(\n    compareArtifactNames,\n  );\n  if (\n    canonicalInvocationPaths.length !== descriptor.invocationPaths.length ||\n    canonicalInvocationPaths.some((entry, index) => entry !== descriptor.invocationPaths[index])\n  ) {\n    throw new Error(\"Invalid Codex runtime invocation descriptor\");\n  }\n}\n\nfunction validateArtifactDescriptorShape(descriptor: CodexRuntimeArtifactDescriptor): void {\n  validateFilesystemDescriptorShape(descriptor);\n  if (\n    typeof descriptor.serverVersion !== \"string\" ||\n    descriptor.serverVersion.length === 0 ||\n    descriptor.serverVersion.length > 128 ||\n    descriptor.serverVersion !== descriptor.serverVersion.trim()\n  ) {\n    throw new Error(\"Invalid Codex runtime server version\");\n  }\n  if (\n    descriptor.userAgentFingerprint !== undefined &&\n    !/^[a-f0-9]{64}$/u.test(descriptor.userAgentFingerprint)\n  ) {\n    throw new Error(\"Invalid Codex runtime user-agent fingerprint\");","sourceCodeStart":712,"sourceCodeEnd":748,"githubUrl":"https://github.com/openclaw/openclaw/blob/01804a75319da4b69c9ab98ceaa30477e22b8c0b/extensions/codex/src/app-server/runtime-artifact.ts#L712-L748","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Build invocationPaths via [...new Set(paths)].sort(compareArtifactNames) before assigning.","Ensure commandRealPath is included exactly once (it must be a member, enforced upstream).","Regenerate the descriptor with captureFilesystemDescriptor so canonical ordering is applied.","Keep invocationPaths length within MAX_ARTIFACT_INVOCATION_PATHS (8)."],"exampleFix":"// before\ninvocationPaths: [a, b, a]\n// after\ninvocationPaths: [...new Set([a, b])].sort(compareArtifactNames)","handlingStrategy":"validation","validationCode":"function canonicalizeInvocationPaths(paths: string[]): string[] {\n  const dedup = [...new Set(paths)].sort(compareArtifactNames);\n  if (dedup.length > 8) throw new RangeError(\"too many invocation paths\");\n  return dedup;\n}","typeGuard":"function isCanonicalInvocationPaths(paths: unknown): paths is string[] {\n  if (!Array.isArray(paths) || paths.length === 0 || paths.length > 8) return false;\n  const canon = [...new Set(paths)].sort(compareArtifactNames);\n  return canon.length === paths.length && canon.every((p, i) => p === paths[i]) && paths.every((p) => isBoundedPath(p));\n}","tryCatchPattern":null,"preventionTips":["Always dedupe and sort invocationPaths with compareArtifactNames before assigning.","Ensure commandRealPath is one of the invocationPaths (required upstream).","Regenerate descriptors via captureFilesystemDescriptor so canonicalization is automatic."],"tags":["codex","runtime-artifact","validation","ordering","app-server"],"backgroundTag":null,"analyzedSha":"01804a75319da4b69c9ab98ceaa30477e22b8c0b","analyzedAt":"2026-08-12T04:37:58.197Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}