awslabs / awslabs/agentcore-samples

Agent Registry migration tool: `load --dry-run` fails with FileNotFoundError on Windows due to path length

Open
#1,989 0 comments 0 reactions 0 assignees View on GitHub
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.