MoonshotAI / MoonshotAI/kimi-code

[Bug]: ReadMediaFileTool reports stale stat size instead of actual attached media bytes

Open
#3,380 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

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

Description

What version of Kimi Code is running?

0.1.1, main@58b74cfeab157483eef8a9e4ed8f4b683eecb34d

Which open platform/subscription were you using?

Not applicable; reproduced by directly invoking deterministic local tool code.

Which model were you using?

Not applicable; no model request is made.

What platform is your computer?

macOS arm64

What issue are you seeing?

ReadMediaFileTool builds its model-visible media note from the file size returned by stat, rather than the number of bytes actually read and attached to the model.

If the file contents differ between the metadata check and the later byte read, the tool can attach one byte sequence while telling the model a different size.

For example, with a PNG buffer of 24 bytes accepted by the existing media-read test helpers and a stat.size value of 34, the returned note contains:

Size: 34 bytes.

even though the attached image data is the 24-byte buffer returned by readBytes.

What steps can reproduce the bug?
  1. Check out Kimi Code main at commit 58b74cfeab157483eef8a9e4ed8f4b683eecb34d.

  2. Install dependencies:

npm install
  1. Add this test to packages/agent-core-v2/test/agent/media/tools/read-media.test.ts, inside the existing ReadMediaFileTool describe block:
it('reports the actual attached image byte length in the media note', async () => {
  const png = pngBuffer();
  const staleStatSize = png.length + 10;

  const result = await execute(
    makeTool({
      '/workspace/stale.png': {
        data: png,
        size: staleStatSize,
      },
    }),
    { path: '/workspace/stale.png' },
  );

  const note = noteText(result);
  const parts = outputParts(result);
  const imageUrl = (parts[1] as { imageUrl: { url: string } }).imageUrl.url;

  expect(imageUrl).toBe(
    `data:image/png;base64,${png.toString('base64')}`,
  );
  expect(note).toContain(`Size: ${String(png.length)} bytes.`);
  expect(note).not.toContain(`Size: ${String(staleStatSize)} bytes.`);
});
  1. Run:
npm run test -- \
  packages/agent-core-v2/test/agent/media/tools/read-media.test.ts
  1. Observe that the test fails because the note reports the stale stat.size value.
What is the expected behavior?

The media note should describe the bytes actually attached to the model.

For the reproduction above, the note should contain:

Size: 24 bytes.

It should not report the earlier stat.size value when the later readBytes result has a different length.

Additional information

The current implementation reads metadata before reading the final media bytes:

const stat = await fs.stat(safePath);

It later reads the bytes that are actually attached:

const data = Buffer.from(await fs.readBytes(safePath));

But the note is built with the earlier metadata value:

const note = buildMediaNote({
  kind: fileType.kind,
  mimeType: fileType.mimeType,
  byteSize: stat.size,
  dimensions,
  delivery,
});

The attached media content is derived from data, so the note can become stale if the file changes between stat and readBytes, or if an IHostFileSystem implementation returns metadata that does not exactly match the later byte-read result.

A possible fix is to pass the actual attached byte length into buildMediaNote, for example data.length for untouched/full media paths or the final delivery byte length when the tool attaches transformed media.

Regression coverage should include:

  • unchanged files where stat.size === data.length;
  • files whose stat.size differs from the bytes returned by readBytes;
  • image paths that attach the original bytes;
  • image paths that attach compressed or cropped bytes;
  • video paths;
  • preservation of existing MIME type and dimension notes.
Contribution
  • 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/test/agent/media/tools/read-media.test.ts and inspect the ReadMediaFileTool implementation around fs.stat, fs.readBytes, and buildMediaNote. Run the focused npm test command from the issue, then verify the note reports the bytes actually attached for unchanged, stale-stat, transformed image, and video paths while preserving MIME and dimension notes.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
cli
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
84/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.