microsoft / microsoft/apm

[BUG] Lockfile writes replace symlinks instead of updating their targets

Open Beginner friendly
#2,993 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

area/lockfile status/deferred theme/security triage/recommended type/feature
Dominant language
Python
Stars
3.8k
Forks
362
Avg merge
1d 17h
Merged PRs (30d)
132

Description

Describe the bug

When lock state changes, APM replaces a symlinked apm.lock.yaml with a regular file and leaves the link target unchanged.

This breaks setups where project or global lockfiles are symlinked to shared locations or dotfiles repositories.

To Reproduce

  1. Create an apm.yml and a shared.lock.yaml that needs updating.
  2. Run ln -s shared.lock.yaml apm.lock.yaml.
  3. Run apm lock.

apm.lock.yaml is now a regular file; shared.lock.yaml is unchanged.

Expected behavior

APM preserves the symlink and writes the updated lockfile atomically to its target. If the target does not exist, APM creates it.

Environment (please complete the following information):

  • OS: Linux
  • Python Version: 3.12.14
  • APM Version: 0.29.0
  • VSCode Version (if relevant): N/A

Logs

The command exits successfully despite breaking the link:

[+] Lockfile written to apm.lock.yaml

Additional context

LockFile.write() passes the symlink to atomic_write_text(), whose os.replace() call replaces the link itself. Resolving the final symlink before the atomic write preserves the link and updates its target.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start at LockFile.write() and atomic_write_text(), then reproduce the issue with a symlinked apm.lock.yaml and run apm lock. Done means the symlink remains in place, its target receives the updated lockfile atomically, and a missing target is created.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
cli, tooling
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
76/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.