simonw / simonw/docs-for-llms

build-docs.sh: find-error check can never fire (PIPESTATUS cannot see inside process substitution)

Open Beginner friendly
#8 0 comments 0 reactions 0 assignees View on GitHub

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:

  1. find runs inside a process substitution < <( ... ). PIPESTATUS in the parent shell only ever reflects pipelines executed directly by the parent — it can never report the exit status of a command inside <( ).
  2. By the time line 212 executes, the [ ${#FOUND_FILES[@]} -eq 0 ] test itself is the most recent pipeline, so PIPESTATUS[0] is ['s own status (0 when the count check passes... and 1 exactly when it enters this branch), never find'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

  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 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.