openclaw/openclaw · warning · CodexPluginThreadConfigDeadlineError

Codex plugin thread config deadline elapsed

Error message

Codex plugin thread config deadline elapsed

What it means

Thrown as CodexPluginThreadConfigDeadlineError when the total budget for building Codex plugin thread config has been exhausted. The deadline is computed as requestTimeoutMs/4 clamped to [100ms, 60000ms]. If a subsequent RPC within the config build discovers that the remaining time budget has dropped to zero or below, this error short-circuits before making the request. It is caught internally and either re-thrown as AgentHarnessPreflightError (fail-closed mode) or triggers a timeout fallback that disables plugin apps for the turn.

Source

Thrown at extensions/codex/src/app-server/plugin-thread-config-deadline.ts:114

          .toSorted()
      : undefined,
  };
}

/** Builds plugin config without allowing sequential RPC timeouts to consume the turn. */
async function buildCodexPluginThreadConfigWithinDeadline(
  params: BuildCodexPluginThreadConfigWithinDeadlineParams,
): Promise<CodexPluginThreadConfig> {
  const { requestTimeoutMs, signal, request, failClosedOnTimeout, transform, ...buildParams } =
    params;
  const timeoutMs = resolveCodexPluginThreadConfigTimeoutMs(requestTimeoutMs);
  // One deadline owns the whole config build; every RPC gets only the remaining
  // budget so discovery cannot consume one full request timeout per call.
  const deadlineMs = Date.now() + timeoutMs;
  const boundedRequest: CodexPluginRuntimeRequest = (method, requestParams) => {
    const remainingTimeoutMs = deadlineMs - Date.now();
    if (remainingTimeoutMs <= 0) {
      throw new CodexPluginThreadConfigDeadlineError();
    }
    return request(method, requestParams, {
      timeoutMs: remainingTimeoutMs,
      signal,
    });
  };
  try {
    return await withAbortableTimeout({
      signal,
      timeoutMs,
      promise: (async () => {
        const config = await buildCodexPluginThreadConfig({
          ...buildParams,
          request: boundedRequest,
        });
        return transform ? await transform(config, boundedRequest) : config;
      })(),
      timeoutMessage: "Codex plugin thread config deadline elapsed",

View on GitHub (pinned to 01804a7531)

Solutions

  1. Increase the Codex request timeout in the plugin config so the derived deadline (timeout/4) is large enough for all discovery RPCs.
  2. Reduce the number of enabled Codex plugins to lower the number of RPCs needed during config discovery.
  3. Check the Codex app-server health and latency — a slow app-server is the most common root cause.
  4. For remote setups, reduce network latency or use a local app-server.
  5. If this is a scheduled automation (fail-closed mode), reauthorize after the app-server is responsive again.
Defensive patterns

Strategy: try-catch

Type guard

function isCodexPluginThreadConfigTimeoutError(error: unknown): boolean {
  return (
    error instanceof Error &&
    (error.name === 'CodexPluginThreadConfigDeadlineError' ||
      ('code' in error &&
        (error as { code?: string }).code === 'CODEX_APP_SERVER_LOCAL_REQUEST_CANCELLED' &&
        error.message.endsWith(' timed out')))
  );
}

Try / catch

// The deadline error is caught internally by buildCodexPluginThreadConfigWithinDeadline.
// For callers of the build function, it either re-throws (fail-closed) or returns a fallback config.
// To handle externally:
try {
  const config = await startupProvider.build({ threadId });
} catch (error) {
  if (error instanceof AgentHarnessPreflightError) {
    // scheduled automation failed closed; retry later
  }
}

Prevention

When it happens

Trigger: During buildCodexPluginThreadConfig, the boundedRequest wrapper checks deadlineMs - Date.now() and if it's <= 0, throws immediately without making the RPC. This happens when previous RPCs (config/read, app/installed, etc.) consumed most of the time budget, leaving no time for the next call. Also thrown by the outer withAbortableTimeout wrapper when the overall deadline elapses.

Common situations: The Codex app-server is slow or overloaded, causing individual RPCs to eat most of the budget. A large number of plugin apps requiring multiple config reads and app inventory checks within a tight deadline. A requestTimeoutMs configured too low for the number of plugins. Network latency in remote setups consuming time on each RPC.

Related errors


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