Skip to content

Commit c011ebf

Browse files
siwachabhiAbhimanyu Siwach
andauthored
fix: prevent incorrect entrypoint inference when multiple candidates exist (#313)
- Changed detect_entrypoint() return type from Optional[Path] to List[Path] - Updated CLI layer to handle 0/1/multiple file cases appropriately - Show error listing all files when ambiguous, require explicit path - Updated 5 test cases to validate new list-based behavior Fixes issue where agent.py was incorrectly inferred as entrypoint when both agent.py (implementation) and main.py (actual entrypoint) exist. Users must now explicitly specify path when multiple candidates found. All tests pass (51/51). Pre-commit hooks validated. Co-authored-by: Abhimanyu Siwach <siwabhi@amazon.com>
1 parent ba056fb commit c011ebf

File tree

4 files changed

+42
-20
lines changed

4 files changed

+42
-20
lines changed

.pre-commit-config.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ repos:
33
# PRE-COMMIT STAGE (Fast, Auto-fixing)
44
# Runs on every commit
55
# ========================================
6-
6+
77
# uv lock file management
88
- repo: https://github.com/astral-sh/uv-pre-commit
99
rev: 0.7.13
@@ -98,4 +98,4 @@ ci:
9898
submodules: false
9999

100100
default_install_hook_types: [pre-commit, pre-push]
101-
default_stages: [pre-commit]
101+
default_stages: [pre-commit]

src/bedrock_agentcore_starter_toolkit/cli/runtime/commands.py

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -162,20 +162,28 @@ def _detect_entrypoint_in_source(source_path: str, non_interactive: bool = False
162162
# Use operations layer for detection
163163
detected = detect_entrypoint(source_dir)
164164

165-
if not detected:
166-
# No fallback prompt - fail with clear error message
165+
if len(detected) == 0:
166+
# No files found - error
167167
rel_source = get_relative_path(source_dir)
168168
_handle_error(
169169
f"No entrypoint file found in {rel_source}\n"
170170
f"Expected one of: main.py, agent.py, app.py, __main__.py\n"
171171
f"Please specify full file path (e.g., {rel_source}/your_agent.py)"
172172
)
173+
elif len(detected) > 1:
174+
# Multiple files found - error with list
175+
rel_source = get_relative_path(source_dir)
176+
files_list = ", ".join(f.name for f in detected)
177+
_handle_error(
178+
f"Multiple entrypoint files found in {rel_source}: {files_list}\n"
179+
f"Please specify full file path (e.g., {rel_source}/main.py)"
180+
)
173181

174-
# Show detection and confirm
175-
rel_entrypoint = get_relative_path(detected)
182+
# Exactly one file - show detection and confirm
183+
rel_entrypoint = get_relative_path(detected[0])
176184

177185
_print_success(f"Using entrypoint file: [cyan]{rel_entrypoint}[/cyan]")
178-
return str(detected)
186+
return str(detected[0])
179187

180188

181189
# Define options at module level to avoid B008

src/bedrock_agentcore_starter_toolkit/operations/runtime/configure.py

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -60,26 +60,30 @@ def get_relative_path(path: Path, base: Optional[Path] = None) -> str:
6060
return str(path_obj)
6161

6262

63-
def detect_entrypoint(source_path: Path) -> Optional[Path]:
64-
"""Detect entrypoint file in source directory.
63+
def detect_entrypoint(source_path: Path) -> List[Path]:
64+
"""Detect entrypoint files in source directory.
6565
6666
Args:
6767
source_path: Directory to search for entrypoint
6868
6969
Returns:
70-
Path to detected entrypoint file, or None if not found
70+
List of detected entrypoint files (empty list if none found)
7171
"""
7272
ENTRYPOINT_CANDIDATES = ["agent.py", "app.py", "main.py", "__main__.py"]
7373

7474
source_dir = Path(source_path)
75+
found_files = []
76+
7577
for candidate in ENTRYPOINT_CANDIDATES:
7678
candidate_path = source_dir / candidate
7779
if candidate_path.exists():
80+
found_files.append(candidate_path)
7881
log.debug("Detected entrypoint: %s", candidate_path)
79-
return candidate_path
8082

81-
log.debug("No entrypoint found in %s", source_path)
82-
return None
83+
if not found_files:
84+
log.debug("No entrypoint found in %s", source_path)
85+
86+
return found_files
8387

8488

8589
def detect_requirements(source_path: Path):

tests/operations/runtime/test_configure.py

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2290,7 +2290,7 @@ def test_detect_entrypoint_not_found(self, tmp_path):
22902290
empty_dir.mkdir()
22912291

22922292
result = detect_entrypoint(empty_dir)
2293-
assert result is None
2293+
assert result == []
22942294

22952295
def test_detect_entrypoint_finds_agent_py(self, tmp_path):
22962296
"""Test detect_entrypoint finds agent.py."""
@@ -2300,7 +2300,9 @@ def test_detect_entrypoint_finds_agent_py(self, tmp_path):
23002300
agent_file.write_text("# agent")
23012301

23022302
result = detect_entrypoint(test_dir)
2303-
assert result == agent_file
2303+
assert isinstance(result, list)
2304+
assert len(result) == 1
2305+
assert result[0] == agent_file
23042306

23052307
def test_detect_entrypoint_finds_app_py(self, tmp_path):
23062308
"""Test detect_entrypoint finds app.py when agent.py doesn't exist."""
@@ -2310,7 +2312,9 @@ def test_detect_entrypoint_finds_app_py(self, tmp_path):
23102312
app_file.write_text("# app")
23112313

23122314
result = detect_entrypoint(test_dir)
2313-
assert result == app_file
2315+
assert isinstance(result, list)
2316+
assert len(result) == 1
2317+
assert result[0] == app_file
23142318

23152319
def test_detect_entrypoint_finds_main_py(self, tmp_path):
23162320
"""Test detect_entrypoint finds main.py when agent.py and app.py don't exist."""
@@ -2320,10 +2324,12 @@ def test_detect_entrypoint_finds_main_py(self, tmp_path):
23202324
main_file.write_text("# main")
23212325

23222326
result = detect_entrypoint(test_dir)
2323-
assert result == main_file
2327+
assert isinstance(result, list)
2328+
assert len(result) == 1
2329+
assert result[0] == main_file
23242330

23252331
def test_detect_entrypoint_priority_order(self, tmp_path):
2326-
"""Test detect_entrypoint follows priority order: agent.py > app.py > main.py."""
2332+
"""Test detect_entrypoint returns all matching files in priority order."""
23272333
test_dir = tmp_path / "test"
23282334
test_dir.mkdir()
23292335

@@ -2336,8 +2342,12 @@ def test_detect_entrypoint_priority_order(self, tmp_path):
23362342
main_file.write_text("# main")
23372343

23382344
result = detect_entrypoint(test_dir)
2339-
# Should find agent.py first (highest priority)
2340-
assert result == agent_file
2345+
# Should return all three files in priority order
2346+
assert isinstance(result, list)
2347+
assert len(result) == 3
2348+
assert result[0] == agent_file # First in priority
2349+
assert result[1] == app_file # Second in priority
2350+
assert result[2] == main_file # Third in priority
23412351

23422352
def test_infer_agent_name_with_py_extension(self, tmp_path):
23432353
"""Test infer_agent_name removes .py extension."""

0 commit comments

Comments
 (0)