build-docs.sh: find-error check can never fire (PIPESTATUS cannot see inside process substitution)
Nobody has claimed this yet.
- Dominant language
- Shell
- Stars
- 60
- Forks
- 3
- PR merge metrics
- No merged PRs in 30d
Description
The find-error check in build-docs.sh is structurally dead code — real find failures are always misreported as "no files found".
The defect
In the default-extensions branch (~line 204–218):
FOUND_FILES=()
while IFS= read -r -d '' file; do
FOUND_FILES+=("$file")
done < <(find "$DEFAULT_DOCS_DIR/" -maxdepth 10 -type f \( "${find_args[@]}" \) -print0 | sort -zV) || true
if [ ${#FOUND_FILES[@]} -eq 0 ]; then
if [[ ${PIPESTATUS[0]} -ne 0 && ${PIPESTATUS[0]} -ne 1 ]]; then
echo "Warning: Error running 'find' command in '$DEFAULT_DOCS_DIR' for tag '$TAG'."
else
echo "Warning: No files with extensions ... found ..."
fi
Two independent reasons this can never fire:
findruns inside a process substitution< <( ... ).PIPESTATUSin the parent shell only ever reflects pipelines executed directly by the parent — it can never report the exit status of a command inside<( ).- By the time line 212 executes, the
[ ${#FOUND_FILES[@]} -eq 0 ]test itself is the most recent pipeline, soPIPESTATUS[0]is['s own status (0when the count check passes... and1exactly when it enters this branch), neverfind's.
Repro (stock repo)
# point DEFAULT_DOCS_DIR at a missing directory and run the branch logic:
# find prints "find: /nonexistent-dir/: No such file or directory" to stderr,
# but the script reports:
# Warning: No files with extensions (...) found in '...' for tag '<TAG>'.
# instead of the intended error message.
Practical impact during a real build: if docs/ is renamed or a checkout is broken for some tag, the operator sees "no docs found" (looks like an old tag that legitimately had no docs dir) instead of "find errored", which points at a different root cause.
Minimal fix
Route the pipeline through a temp file so its status is directly observable by the parent:
- FOUND_FILES=()
- while IFS= read -r -d '' file; do
- FOUND_FILES+=("$file")
- done < <(find "$DEFAULT_DOCS_DIR/" -maxdepth 10 -type f \( "${find_args[@]}" \) -print0 | sort -zV) || true
+ FOUND_FILES=()
+ FIND_TMP=$(mktemp)
+ FIND_STATUS=0
+ find "$DEFAULT_DOCS_DIR/" -maxdepth 10 -type f \( "${find_args[@]}" \) -print0 \
+ | sort -zV > "$FIND_TMP" || FIND_STATUS=$?
+ while IFS= read -r -d '' file; do
+ FOUND_FILES+=("$file")
+ done < "$FIND_TMP"
+ rm -f "$FIND_TMP"
and change the guard from ${PIPESTATUS[0]} to $FIND_STATUS.
Verified post-fix behavior (with set -eEo pipefail, matching the script):
| case | result |
|---|---|
| missing docs dir | Warning: Error running 'find' command (status 1) ✓ |
valid dir with .md files |
Found 2 file(s) ✓ |
| valid dir, wrong extensions only | No files ... found ✓ |
Happy to send this as a PR if useful.
I run FreshContext ($5, version-anchored context packs for AI coding agents — current-doc links, deprecated-pattern traps, verification commands). This repo is basically the gold standard of that problem space, so no pitch needed here — just flagging the bug.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in build-docs.sh at the default-extensions branch around lines 204–218, where find runs inside process substitution and PIPESTATUS is checked. Reproduce the missing-directory case, then verify the reported find status, valid directories with matching files, and directories with no matching extensions. Done means these three cases produce the expected warnings or file count without relying on PIPESTATUS from process substitution.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- shell
- Domain
- build-system, documentation
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 84/100