awslabs / awslabs/agentcore-samples
Agent Registry migration tool: `load --dry-run` fails with FileNotFoundError on Windows due to path length
- Dominant language
- Python
- Stars
- 3.4k
- Forks
- 1.3k
- Avg merge
- 1d 22h
- Merged PRs (30d)
- 30
Description
### Summary
Running the documented one-time migration flow fails during `load --dry-run` on Windows.
The extraction completes successfully and pre-flight validation passes, but the load stage fails while creating its attempt lock file. The error is a `FileNotFoundError` from `os.open()`, even though the parent directory exists.
The failure appears to be caused by the Windows legacy maximum path length. The attempted lock-file path is exactly 260 characters long.
### Environment
- Operating system: Windows, `Microsoft Windows NT 10.0.26200.0`
- PowerShell: `7.6.5`
- Node.js: `v24.12.0`
- npm: `11.6.2`
- Python: `3.13.12`
- Python executable:
```text
...\04-migrate-to-new-namespace\agentregistrymigration\.venv\Scripts\python.exe
```
- boto3: `1.43.78`
- botocore: `1.43.78`
- Required service models available:
```text
bedrock-agentcore-control
agent-registry-control
```
The tool was installed from the repository using:
```powershell
npm install
npm run build
npm link
```
### Reproduction steps
1. Clone the repository into a deeply nested Windows path, for example:
```text
C:\Github\awslabs\agentcore-samples\01-features\07-centralize-and-govern-your-ai-infrastructure\03-registry\04-migrate-to-new-namespace
```
2. Create and activate the Python virtual environment:
```powershell
python -m venv agentregistrymigration\.venv
.\agentregistrymigration\.venv\Scripts\activate
```
3. Install the Python dependencies:
```powershell
python -m pip install -r requirements-dev.txt
```
4. Build and link the CLI:
```powershell
npm install
npm run build
npm link
```
5. Run the documented migration steps:
```powershell
agent-registry-migration init
agent-registry-migration check
agent-registry-migration extract
agent-registry-migration load --dry-run
```
6. The extraction succeeds, but `load --dry-run` fails while creating the transform/load attempt lock.
### Expected behavior
`load --dry-run` should create the attempt lock and continue transforming the extracted records without writing anything to the target registry.
### Actual behavior
Pre-flight validation passes:
```text
Pre-flight validation PASSED
Transforming and reporting...
```
The command then fails with:
```text
FileNotFoundError: [Errno 2] No such file or directory:
'C:\Github\awslabs\agentcore-samples\01-features\07-centralize-and-govern-your-ai-infrastructure\03-registry\04-migrate-to-new-namespace\migration-runs\state\locks\run_id=20260824T141511Z-c998de1b\transform-load-attempt=63d5b70a-8484-49c0-86a4-fcbf0020ce2a.json'
```
The relevant code path is:
```python
path = self._path(key)
path.parent.mkdir(parents=True, exist_ok=True)
descriptor = os.open(
path,
os.O_CREAT | os.O_EXCL | os.O_WRONLY,
)
```
The parent directory exists, but opening the full file path fails.
### Additional evidence
The failed path has the following lengths:
```text
Workspace path: 135 characters
Failed lock-file path: 260 characters
```
A direct Windows filesystem check reproduced the behavior:
- `os.open()` using the normal path failed with `FileNotFoundError`
- `os.open()` using the Windows extended path prefix (`\\?\`) succeeded
This suggests that the error is related to Windows path handling rather than missing directories, AWS permissions, boto3, or botocore.
### Workaround
Moving the repository to a shorter path allows the command to proceed. For example:
```text
C:\src\agent-registry-migration
```
### Possible fix
The local filesystem store could use Windows extended-length paths for filesystem operations, for example by converting paths to the `\\?\` form before calls to `os.open`, `open`, `os.replace`, and related filesystem APIs. Alternatively, the tool could detect this condition and provide a clearer error explaining that the staging path is too long.
Contributor guide
Research direction
Start at the local filesystem store code path that builds the lock-file path and calls os.open(), then reproduce the documented migration flow on Windows with a deeply nested workspace. Check the related filesystem operations named in the issue, including open and os.replace. Done means load --dry-run creates its attempt lock and continues successfully at the reported path length without writing to the target registry.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- cli, tooling
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 68/100