MoonshotAI / MoonshotAI/kimi-code

Background Bash ignores configured bash_task_timeout_s (and print mode's 0) — tasks hard-killed at 600s despite config/docs promise

Open Beginner friendly
#3,187 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
TypeScript
Stars
7.5k
Forks
1.2k
Avg merge
11h 53m
Merged PRs (30d)
350

Description

Version

main @ 9a715820c (verified against current source)

Platform

All platforms (engine-level)

What issue are you seeing?

When a Bash tool call starts in the background (run_in_background=true) without an explicit timeout argument, the v2 engine always arms the task with the hardcoded 600-second default. The configured task.bash_task_timeout_s value — including 0 (no timeout), which is the documented default in print mode (kimi -p) — is silently ignored. Long-running background builds/tests are SIGTERM-killed at exactly 600 s with status timed_out, and in print mode this directly violates the documented guarantee that "background work is never killed by a wall-clock cap in print mode".

Root cause

packages/agent-core-v2/src/agent/tools/os/bash/bashTool.ts:183-186:

const timeoutMs = startsInBackground
  ? args.disable_timeout
    ? undefined
    : normalizeTimeoutMs(args.timeout, true)   // ← never consults config
  : foregroundTimeoutMs;

normalizeTimeoutMs(undefined, true) falls back to DEFAULT_BACKGROUND_TIMEOUT_S (600, bash.ts:8).

The config-aware path exists in the same file but is only used for the detach re-arm of a foreground command that timed out:

private detachTimeoutMs(): number {
  const configuredS = resolveAgentTaskConfig(this.config)?.bashTaskTimeoutS;
  if (configuredS === undefined) return DEFAULT_BACKGROUND_TIMEOUT_S * MS_PER_SECOND;
  return configuredS * MS_PER_SECOND;
}

The legacy v1 engine honored the config for the background-start default (packages/agent-core/src/tools/builtin/shell/bash.ts, backgroundDefaultTimeoutMs), so this is a v2 regression.

Documentation promises the config works (docs/en/configuration/config-files.md:351):

bash_task_timeout_s … Default timeout (seconds) for background Bash tasks when the call omits timeout0 means no timeout … In print mode (kimi -p) the default is 0 unless explicitly set.

and print mode (config-files.md:358):

Background work is never killed by a wall-clock cap in print mode either: background Bash tasks default to no timeout (bash_task_timeout_s = 0)…

applyPrintModeConfigDefaults (packages/agent-core-v2/src/agent/task/printDefaults.ts:39-46) does set bashTaskTimeoutS = 0 into config memory for kimi -p — but BashTool never reads it for background starts, so the setting is dead.

Steps to reproduce

Unit-level repro against current source (vitest, fake task service captures the options BashTool passes to registerTask):

it('print mode (bash_task_timeout_s = 0) → background task armed with NO timeout', async () => {
  const tool = buildTool((section) =>
    section === 'task' ? { bashTaskTimeoutS: 0 } : undefined);
  await tool.resolveExecution({
    command: 'sleep 3600',
    description: 'long background job',
    run_in_background: true,   // no explicit timeout — the documented common case
  }).execute({ signal: new AbortController().signal });
  const options = capturedRegisterTaskOptions();
  expect(options.timeoutMs).toBeUndefined(); // docs: 0 = no timeout
});

Observed:

AssertionError: expected 600000 to be undefined

and with bashTaskTimeoutS: 3600 configured, the captured timeoutMs is still 600000 — the config is ignored in both directions.

End-to-end: set bash_task_timeout_s = 0 (or just run kimi -p, which sets it implicitly), start any background Bash call without timeout/disable_timeout (the tool description nudges disable_timeout only defensively, so most model calls omit it), and watch the task settle as timed_out at exactly 600 s.

Expected behavior

For a background start without explicit timeout and without disable_timeout, arm the task with resolveAgentTaskConfig(config).bashTaskTimeoutS (falling back to 600 s only when unset), treating 0 as no timeout — matching the detach re-arm path, the v1 engine, the config docs, and the print-mode guarantee.

Additional information

  • The existing test packages/agent-core-v2/test/os/backends/node-local/tools/bash.test.ts covers the detach re-arm honoring the config, but not the background-start path — which is how this regression slipped in.

  • Workaround for users: pass disable_timeout: true on every background call; but the model has no way to know the configured default is being ignored, and print mode users get no warning that the documented no-timeout guarantee is not in effect.

  • I am willing to submit a PR for this bug fix myself (please wait for maintainer approval in this issue first)

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in packages/agent-core-v2/src/agent/tools/os/bash/bashTool.ts at the background timeout selection and compare it with detachTimeoutMs(). Read the related configuration handling and printDefaults.ts, then run packages/agent-core-v2/test/os/backends/node-local/tools/bash.test.ts. Done means background starts honor the configured value, including 0, while the existing fallback and explicit timeout behavior remain covered.

Written by the indexing model from the issue text.

Assessment

Tech stack
bash, typescript
Domain
backend, cli, testing-qa
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
86/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.