garrytan/gstack · warning · PdftotextUnavailableError
pdftotext not found. make-pdf needs pdftotext to run the co
Error message
pdftotext not found.
make-pdf needs pdftotext to run the copy-paste CI gate.
(Runtime rendering does NOT need it. This only affects tests.)
To install:
macOS: brew install poppler
Ubuntu: sudo apt-get install poppler-utils
Fedora: sudo dnf install poppler-utils
Windows: scoop install poppler (or download from
https://github.com/oschwartz10612/poppler-windows)
Or set GSTACK_PDFTOTEXT_BIN to an explicit path:
${GSTACK_PDFTOTEXT_BIN export/setx line} What it means
PdftotextUnavailableError thrown by resolvePdftotext() when the pdftotext binary cannot be found via GSTACK_PDFTOTEXT_BIN/PDFTOTEXT_BIN env overrides, PATH lookup (Bun.which), or the POSIX standard locations (/opt/homebrew/bin, /usr/local/bin, /usr/bin). Note: runtime PDF rendering does NOT need pdftotext — only the copy-paste CI gate does. The message is a per-platform install recipe.
Source
Thrown at make-pdf/src/pdftotext.ts:97
// 3: PATH lookup via Bun.which — handles Windows PATHEXT natively.
const PATH = env.PATH ?? env.Path ?? '';
const onPath = Bun.which('pdftotext', { PATH });
if (onPath) return describeBinary(onPath);
// 4: POSIX-only standard locations. No Windows candidates — Poppler installs
// scatter across Scoop/Chocolatey/portable zips and guessing causes false
// positives. Windows users set GSTACK_PDFTOTEXT_BIN explicitly.
const posixCandidates = [
"/opt/homebrew/bin/pdftotext", // Apple Silicon Homebrew
"/usr/local/bin/pdftotext", // Intel Mac or Linuxbrew
"/usr/bin/pdftotext", // distro package
];
for (const candidate of posixCandidates) {
if (isExecutable(candidate)) return describeBinary(candidate);
}
throw new PdftotextUnavailableError([
"pdftotext not found.",
"",
"make-pdf needs pdftotext to run the copy-paste CI gate.",
"(Runtime rendering does NOT need it. This only affects tests.)",
"",
"To install:",
" macOS: brew install poppler",
" Ubuntu: sudo apt-get install poppler-utils",
" Fedora: sudo dnf install poppler-utils",
" Windows: scoop install poppler (or download from",
" https://github.com/oschwartz10612/poppler-windows)",
"",
"Or set GSTACK_PDFTOTEXT_BIN to an explicit path:",
process.platform === "win32"
? ' setx GSTACK_PDFTOTEXT_BIN "C:\\path\\to\\pdftotext.exe"'
: " export GSTACK_PDFTOTEXT_BIN=/path/to/pdftotext",
].join("\n"));
}View on GitHub (pinned to 94993f7401)
Solutions
- Install poppler: `brew install poppler` (macOS), `sudo apt-get install poppler-utils` (Ubuntu), `sudo dnf install poppler-utils` (Fedora), `scoop install poppler` (Windows).
- Set GSTACK_PDFTOTEXT_BIN to an absolute pdftotext path (`export GSTACK_PDFTOTEXT_BIN=/usr/local/bin/pdftotext`).
- Skip the affected test gate if pdftotext is optional in your flow.
- On Windows, download poppler-windows and setx GSTACK_PDFTOTEXT_BIN to the bin/pdftotext.exe path.
Example fix
# before $ bun test Error: pdftotext not found. ... # after — install poppler $ brew install poppler $ bun test
Defensive patterns
Strategy: validation
Validate before calling
import { resolvePdftotext, PdftotextUnavailableError } from './pdftotext';
function ensurePdftotext(): void {
try { resolvePdftotext(); }
catch (e) {
if (e instanceof PdftotextUnavailableError) {
throw new Error('pdftotext missing — install poppler or set GSTACK_PDFTOTEXT_BIN. Tests only; rendering unaffected.');
}
throw e;
}
}
ensurePdftotext(); Type guard
import { PdftotextUnavailableError } from './pdftotext';
function isPdftotextMissing(e: unknown): e is PdftotextUnavailableError {
return e instanceof PdftotextUnavailableError;
} Try / catch
try {
const text = pdftotext(pdfPath);
} catch (e) {
if (e instanceof PdftotextUnavailableError) {
console.warn('skipping copy-paste gate: pdftotext not installed');
return; // non-fatal for local dev
}
throw e;
} Prevention
- Install poppler in every CI image that runs the test suite.
- Set GSTACK_PDFTOTEXT_BIN to an absolute path in CI for reproducibility.
- Treat the absence as test-only — never block a render on it.
- Document the dependency in the repo's setup instructions.
When it happens
Trigger: Calling pdftotext() (or the CI gate that uses it) on a machine without poppler installed and without GSTACK_PDFTOTEXT_BIN set. On Windows there are no standard-location guesses; the env override is required.
Common situations: A new dev machine without poppler; CI that runs the test suite but never installed poppler-utils; a Windows user who did not set GSTACK_PDFTOTEXT_BIN; a minimal Docker image that omitted poppler to save size; Homebrew installed to a non-standard prefix.
Related errors
- 127
- diagram-render bundle not found. Tried: ${candidates.map((c)
- pdftotext failed on ${pdfPath}: ${err.message}
- browse ${args[0] || "unknown"} exited ${exitCode}: ${stderr}
- 1
AI-assisted analysis of garrytan/gstack@94993f7401 (2026-08-12).
Data as JSON: /api/errors/0fbe0f481921301d.
Report an issue: GitHub.