con / con/git-annex

Chained compute remotes always report checkPresent=False (cycle guard adds current key to ancestor set)

Open Beginner friendly
#272 0 comments 0 reactions 0 assignees View on GitHub
ai-uncurated bug
Dominant language
Python
Stars
29
Forks
5
PR merge metrics
No merged PRs in 30d

Description

Chained compute remotes break: a compute remote whose input is itself a
computed file (output of another compute remote) always reports
`checkPresent = False`, regardless of whether the input is actually
reachable.

```
> git -C main annex fsck --from=cr1 mid.txt # depth-1: works
fsck mid.txt (cr1) ok

> git -C main annex fsck --from=cr2 out.txt # depth-2: cr2 needs mid.txt, mid.txt computable via cr1
fsck out.txt (cr2)
** Failed to verify content of out.txt (cr2):
expected to be present, but its content is missing
```

Introduced together with the compute special remote in `10.20250320`
(commit 70cb93a66b "checkPresent of compute remote checks inputs are
available"). Code unchanged through `10.20260525` (current upstream).

Root cause

`Remote/Compute.hs:827-847`:

```haskell
availablecompute inputkeys deadset computeset k' rs'
| k' `elem` inputkeys = return False -- line 827-828
| …
| otherwise = do
cs <- getComputeStatesUnsorted rs' k'
anyM
(\computestate ->
all id <$> mapM
(\k'' -> hasinputs k'' (computeStateRemoteState computestate)
<|||> availablecompute (k':inputkeys) deadset computeset k' -- line 847
. RemoteStateHandle
=<< computeStateInputs computestate k''
)
(computeStateInputs computestate))
cs
```

The recursive call passes `k'` as BOTH the new ancestor (`k':inputkeys`) AND
the next-key argument. On the very next descent, `k' \`elem\` (k':inputkeys)`
is unconditionally `True`, so the recursion returns `False` before
`getComputeStatesUnsorted` ever runs on the upstream remote.

The `inputkeys` set's purpose is "ancestor outputs we're already trying to
compute" — adding the *current input* to it on the recursive descent is
incorrect.

Suggested fix: drop the `k':` prefix on line 847, leaving
`availablecompute inputkeys deadset computeset k' . RemoteStateHandle =<< …`.

Reproducer (POSIX shell, exits non-zero when bug fires)

See `reproducer-compute-cycle-depth.sh` — two compute programs chained, with
the depth-1 fsck as a positive control and depth-2 fsck as the failing case.

Version

```
Verified with: git-annex 10.20260421
Confirmed present in: 10.20260525 (Remote/Compute.hs untouched in the interim)
```

Contributor guide

No contributing guide indexed for this repository

Research direction

Start in Remote/Compute.hs around lines 827-847, then inspect reproducer-compute-cycle-depth.sh. Verify the cycle guard and recursive call against the issue's described ancestor-set behavior. Run the reproducer and confirm both the depth-1 control and chained depth-2 fsck succeed without the missing-content failure.

Written by the indexing model from the issue text.

Assessment

Tech stack
haskell, shell
Domain
cli, tooling
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
85/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.