microsoft / microsoft/aspire

Agent init cannot refresh a locked telemetry hook and reports an unclear access error

Open
#19,945 0 comments 0 reactions 0 assignees View on GitHub
area-cli
Dominant language
C#
Stars
6.3k
Forks
991
Avg merge
2d 15h
Merged PRs (30d)
196

Description

### Is there an existing issue for this?

- [x] I have searched the existing issues

### Describe the bug

On Windows, `aspire agent init` cannot refresh `ASPIRE_HOME\hooks\track-telemetry.ps1` when the existing script is temporarily open without delete/write sharing, which can happen while the telemetry hook is executing.

The installer writes the updated content to a sibling `track-telemetry.ps1.tmp-*` file, but the atomic replacement fails. The command then displays only:

```text
Access to the path is denied.
```

It immediately follows that with `Agent environment configuration complete.` and exits with code `0`. The existing hook remains stale, the temporary file is stranded, and the message does not identify the file, operation, or affected client.

This reproduces on current `main` at `ff714afede575552c75d3de9584a643d98b6690e` with CLI version `13.6.0-dev`.

### Expected Behavior

Refreshing telemetry hooks should tolerate a short-lived lock, for example with a bounded retry or safe deferred replacement. If the refresh still cannot complete, the CLI should identify the affected hook path/client and should clean up the sibling temporary file rather than reporting only a generic access-denied message followed by an unqualified success message.

### Steps To Reproduce

Build the CLI from current `main`, then run the following from PowerShell in a scratch directory. This uses isolated Aspire and Copilot homes.

```powershell
$workspace = Join-Path $PWD "workspace"
$env:ASPIRE_HOME = Join-Path $PWD "aspire-home"
$env:COPILOT_HOME = Join-Path $PWD "copilot-home"
$env:TERM_PROGRAM = "vscode"

New-Item -ItemType Directory -Force `
(Join-Path $workspace ".vscode"), `
(Join-Path $env:ASPIRE_HOME "hooks"), `
$env:COPILOT_HOME | Out-Null

$hook = Join-Path $env:ASPIRE_HOME "hooks\track-telemetry.ps1"
Set-Content -LiteralPath $hook -Value "# stale hook content"

# Allow reads but deny writes/deletion, simulating a concurrently executing hook.
$lock = [System.IO.File]::Open(
$hook,
[System.IO.FileMode]::Open,
[System.IO.FileAccess]::Read,
[System.IO.FileShare]::Read)

try {
aspire agent init `
--workspace-root $workspace `
--skill-locations none `
--skills none `
--non-interactive `
--nologo
}
finally {
$lock.Dispose()
}

$LASTEXITCODE
Get-ChildItem -LiteralPath (Join-Path $env:ASPIRE_HOME "hooks") -Filter "track-telemetry.ps1.tmp-*"
```

Observed output:

```text
🤖 Detecting agent environments...
Access to the path is denied.
✅ Agent environment configuration complete.
```

The exit code is `0`, and `track-telemetry.ps1.tmp-*` remains in the hooks directory.

### Exceptions (if any)

No exception type, stack trace, path, or client name is surfaced to the user. The access-denied text comes from the broad best-effort catch around `ITelemetryHookConfigurator.ConfigureAsync`.

### Aspire doctor output

N/A — the failure is reproduced by locking the existing telemetry hook during refresh and is not dependent on Aspire environment health.

### Anything else?

- **Environment:** Windows ARM64, PowerShell, .NET 10
- **Aspire CLI:** `13.6.0-dev`, main commit `ff714afede575552c75d3de9584a643d98b6690e`
- `TelemetryHookInstaller.WriteIfChangedAsync` writes a sibling temp file and then calls `File.Move(tempPath, path, overwrite: true)` without retry or cleanup when replacement fails.
- The failure occurs before the per-client write-result handling in `TelemetryHookConfigurator`, so `AgentInitCommand.ConfigureTelemetryHooksAsync` catches the exception and displays only `ex.Message`.

Contributor guide

Open the contributing guide

Research direction

Start with TelemetryHookInstaller.WriteIfChangedAsync and its File.Move call, then trace how failures flow through TelemetryHookConfigurator and AgentInitCommand.ConfigureTelemetryHooksAsync. Run the supplied PowerShell reproduction; done means locked-hook refreshes are handled within a bounded policy, temporary files are cleaned up, and an incomplete refresh reports the affected hook and client without an unqualified success.

Written by the indexing model from the issue text.

Assessment

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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.