bazelbuild / bazelbuild/bazel

`repository_ctx.symlink` can result in content mimatches

Open
#24,694 26 comments 0 reactions 1 assignee Claimed by @fmeum View on GitHub
P2 team-ExternalDeps type: bug
Dominant language
Java
Stars
25.8k
Forks
4.6k
Avg merge
2d 20h
Merged PRs (30d)
72

Description

### Description of the bug:

This is a race condition bug. When using `repository_ctx.symlink` in a repository rule, and the thing being symlinked is from another repository (in our case the repository that owns the repository rule), Bazel can get confused about the contents of the file. This can result in errors like this:

```
ERROR: error loading package '@@apple_support~~apple_cc_configure_extension~local_config_apple_cc//': Encountered error while reading extension file 'cc_toolchain_config.bzl': Unexpected short read from file '/Users/brentley.jones/Developer/rules_xcodeproj/bazel-output-base/external/apple_support~~apple_cc_configure_extension~local_config_apple_cc/cc_toolchain_config.bzl' (expected 100570, got 95733 bytes)
```

which happens when the new contents of the file is shorter than it was before. Or errors like this:

```
ERROR: /Users/brentley.jones/Developer/rules_xcodeproj/bazel-output-base/external/apple_support~~apple_cc_configure_extension~local_config_apple_cc/cc_toolchain_config.bzl:2667:23: syntax error at 'newline': expected ]
```

---

This seems to indicate that two blocks of reads are being stitched together since line 2663 in the new file is:

```
)
else:
layering_check_feature = feature(name = "layering_check")

features = [
# Marker features
```

and line 2663 in the old file is:

```
DefaultInfo(
executable = out,
),
]

cc_toolchain_config = rule(
```

so it's trying to evaluate something that looks like:

```
features = [

cc_toolchain_config = rule(
```

This also lines up with why the first version of this error is talking about mismatched bytes, because the byte counts are `101176` and `95733`, with `100570` being `606` bytes shorter than expected for the existing file "old", which could only happen if it read two versions of the same file and stitched them together.

So Bazel is reading the file, and it's getting replaced from under it, and it continues reading the file with new contents.

### Which category does this issue belong to?

_No response_

### What's the simplest, easiest way to reproduce this bug? Please provide a minimal example if possible.

I had a workspace depend on 1.15.1 of **apple_support** then flipped it to 1.17.1. I could repro this most of the time flipping that dep back and forth, but a friend I asked to repro this couldn't. This makes sense, being it's a race condition in reading the symlinked file.

### Which operating system are you running Bazel on?

macOS 15.1.1

### What is the output of `bazel info release`?

8.0.0 release (but also 7.1.1 and HEAD)

### If `bazel info release` returns `development version` or `(@non-git)`, tell us how you built Bazel.

_No response_

### What's the output of `git remote get-url origin; git rev-parse HEAD` ?

_No response_

### If this is a regression, please try to identify the Bazel commit where the bug was introduced with bazelisk --bisect.

_No response_

### Have you found anything relevant by searching the web?

_No response_

### Any other information, logs, or outputs that you want to share?

https://github.com/bazelbuild/apple_support/commit/8d477fc1e69c0a1c2ca0ee753a851cf73c763901

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.