Skip to content

fix(harness): make ls() report errors instead of silently returning empty results - #2413

Open
chcodex wants to merge 2 commits into
agentscope-ai:mainfrom
chcodex:fix/filesystem
Open

fix(harness): make ls() report errors instead of silently returning empty results#2413
chcodex wants to merge 2 commits into
agentscope-ai:mainfrom
chcodex:fix/filesystem

Conversation

@chcodex

@chcodex chcodex commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

Fixes #2411

Summary

Three-layer cascade: LocalFilesystem.ls() and BaseSandboxFilesystem.ls() silently return success(empty list) when a path does not exist or is a file (not a directory). This makes FilesystemTool.listFiles() unable to distinguish "not found", "not a directory", and "empty directory" — it returns the same misleading "Empty or not a directory: ..." message for all three.

Changes

LocalFilesystem.ls()

Split the single || check into two separate conditions:

  • !Files.exists(dirPath)LsResult.fail("Path does not exist: ...")
  • !Files.isDirectory(dirPath)LsResult.fail("Not a directory: ...")

BaseSandboxFilesystem.ls()

Added shell-level path existence/directory checks before the glob loop:

if [ ! -e path ]; then echo '\''__NOT_EXISTS__'\''
elif [ ! -d path ]; then echo '\''__NOT_A_DIR__'\''
else for f in path/*; do ... done
fi

Java parses the sentinel values and returns LsResult.fail(...) accordingly.
Also updated FakeSandboxFilesystem.execute() command matching to match the new command prefix.

FilesystemTool.listFiles()

Changed the empty-entries message from "Empty or not a directory" to "Empty directory" — since the other two cases are now caught at the filesystem layer as errors.

Tests

Added 7 reproduction/regression tests across all three layers (previously @Disabled, now active). All 36 tests pass with 0 failures.

…mpty results (agentscope-ai#2411)

LocalFilesystem.ls() and BaseSandboxFilesystem.ls() returned
success(empty list) when the path did not exist or was a file,
making it impossible for callers to distinguish these cases
from an empty directory.

Changes:
- LocalFilesystem.ls(): return fail() with descriptive error for
  non-existent paths and file paths instead of success(empty)
- BaseSandboxFilesystem.ls(): add shell-level path checks before
  the glob loop, parse sentinel values in Java, return fail()
- FilesystemTool.listFiles(): change message from
  "Empty or not a directory" to "Empty directory" since
  the other two cases are now caught as errors at the fs layer
- Add reproduction/regression tests for all three layers
@codecov

codecov Bot commented Jul 27, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 83.33333% with 2 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
...gent/filesystem/sandbox/BaseSandboxFilesystem.java 71.42% 0 Missing and 2 partials ⚠️

📢 Thoughts on this report? Let us know!

@oss-maintainer oss-maintainer left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review — Approved ✅

Overall: Good fix for #2411. The PR correctly changes ls() to return proper error results instead of silently returning empty lists when the path doesn't exist or is not a directory.

Key Changes:

  1. LocalFilesystem.ls(): Now returns LsResult.fail(...) with descriptive messages for non-existent paths and non-directory paths, instead of LsResult.success(List.of()).

  2. BaseSandboxFilesystem.ls(): Added shell-level checks ([ ! -e ... ] and [ ! -d ... ]) with sentinel values (__NOT_EXISTS__, __NOT_A_DIR__) to detect error conditions in the sandbox environment.

  3. FilesystemTool.listFiles(): Updated the empty result message from "Empty or not a directory" to "Empty directory" since the error cases are now handled upstream.

  4. Tests: Added two new test cases verifying that ls() returns failure for non-existent paths and file paths.

Code Quality:

  • ✅ Correct error handling — distinguishes between "path doesn't exist" and "not a directory"
  • ✅ Good test coverage
  • ✅ Sandbox implementation uses sentinel values to communicate errors across the execution boundary
  • ✅ Backward compatible for valid directory paths

CI Status: ✅ All checks passed

Verdict: Well-implemented fix that correctly addresses the silent error swallowing issue. The error messages are clear and actionable.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ls() silently swallows errors in LocalFilesystem and BaseSandboxFilesystem, leading to misleading list_files messages

2 participants