-
Notifications
You must be signed in to change notification settings - Fork 0
Common Errors
Search this page for your literal error string. Every entry below is something that actually happened in this repository, with the message as it appears, not paraphrased.
If you solve something not listed here, add it. The value of this page is entirely its coverage.
Where: the Welcome workflow, on every newly opened issue or PR.
Cause: actions/first-interaction v3 renamed its inputs from kebab-case to snake_case —
issue-message → issue_message, pr-message → pr_message, repo-token → repo_token.
GitHub Actions does not normalise the hyphen, so getInput('issue_message') found nothing.
Fix: rename the inputs in the workflow.
Why it hid: it fails open for the repository — the greet job goes red and nothing else breaks — and closed for the person it exists to serve, who silently gets no welcome. Caught by CI going red on an unrelated PR, not by review of the bump.
Where: a Mermaid diagram, or node tools/validate-mermaid.mjs.
Cause: an unquoted ( or ) inside a [] node label. PI[pipeline.py<br/>evaluate()] fails;
PI["pipeline.py<br/>evaluate()"] parses.
Fix: quote the label. Every label in this repo is quoted for exactly this reason.
Why it hid: on GitHub a diagram that fails to parse renders as nothing — no error, no placeholder, just absence. It shipped once and was only found by parsing every block against the real parser.
node tools/validate-mermaid.mjsWhere: the Pages workflow, at the deploy step, with the build step green.
Cause: GitHub Pages had never been enabled for the repository. The workflow is fine; there is nothing to deploy into.
Fix: Settings → Pages → Source → GitHub Actions. Or:
gh api -X POST repos/OWNER/REPO/pages -f build_type=workflowWhy it hid: the repository's homepage field advertised the Pages URL, so it looked configured.
Where: ruff check, on any file that calls sys.path.insert or matplotlib.use() before
importing.
Cause: the ordering is deliberate — matplotlib.use("Agg") must run before pyplot is
imported, and sys.path.insert must run before a local package import.
Fix: # noqa: E402 with the reason written next to it. Reordering to satisfy the linter
breaks the backend selection or the import.
Where: any matplotlib figure using fontweight="medium".
Cause: DejaVu Sans, matplotlib's default, has no medium weight.
Fix: use "normal" or "bold", or install a font that has one. Harmless warning; the figure
renders.
Where: merging several Dependabot PRs in a row.
Cause: they all edit pyproject.toml. Merging one invalidates the others.
Fix: comment @dependabot rebase on each remaining PR and merge them one at a time.
Where: any shell where the working directory persists between commands.
Cause: you are already inside nanorag/, and there is a Python package directory also called
nanorag/. The second cd nanorag puts you in the package.
Fix: use absolute paths, or git -C /path/to/repo. This has cost real time.
Cause: almost always a different interpreter than the one that ran pip.
Fix:
python -c "import sys; print(sys.executable)"
python -m pip install -e ".[dev]" # -m pins the interpreterCause: a Python built against a SQLite without FTS5. Common on some Linux distribution packages and older conda builds.
Fix:
import sqlite3
print(sqlite3.sqlite_version)
con = sqlite3.connect(":memory:")
print([r for r in con.execute("PRAGMA compile_options") if "FTS5" in r[0]])If FTS5 is absent, install Python from python.org, use the system Python on macOS, or a
python:3.12 container. There is no pure-Python fallback — the lexical leg is FTS5.
Cause: several, and none of them raise. This is the class of bug this repository is mostly about — see Troubleshooting.
The three most common: a tokenizer that split your identifiers, a mixed-encoder index, and a
post-filter that collapsed k.
Where: anything that talks to Projects boards, gh pr checks, gh pr view, create_thread.py,
boards.py — all GraphQL under the hood.
Cause: the GraphQL quota is genuinely spent. gh api rate_limit reports a different
accounting for graphql and can read 5000/5000 for the entire hour the real quota is at zero.
The only honest gauge is the X-Ratelimit-* headers on an actual GraphQL response:
gh api graphql -i -f query='{viewer{login}}' 2>&1 | grep -iE '^x-ratelimit-(remaining|reset|used)'X-Ratelimit-Remaining: 0 with a reset epoch 40 minutes out is the answer; gh api rate_limit
will still say 5000/5000.
What spends it: Projects item-list is priced in points by nodes returned — one list over a
large board can cost hundreds of the hourly 5,000. A polling loop on gh pr checks every 20
seconds is a steady drain. And the quota is shared by every session on the account, so two
agents working the same repo halve each other's budget.
Fix: wait for the reset — there is no way round it. Then stop the drains: cap item-list
page sizes, list a board once per process and cache, never poll gh pr checks in a loop (read
/pulls/{n} and /commits/{sha}/check-runs over REST instead — separate 5,000 budget), and
use gh api -X PUT .../pulls/{n}/merge rather than gh pr merge. scripts/boards.py now reads
the headers and stops with the reset time rather than sleeping through the hour in 90-second
pieces.
Why it hid: the guard checked rate_limit, saw 5000, proceeded, and got refused — three
times in one session — before anyone read the headers.
Where: the scheduled pulse.yml refresh, the tracker step at the end of labs.yml and
discussion-lab.yml, assign.py — anything that writes a Projects board from a workflow.
Cause: PROJECT_TOKEN is a personal access token, and a PAT authenticates as you. The
primary GraphQL limit is 5,000 points per hour per user, not per token. Every PAT you own,
every CI step that carries one, and every terminal you are logged into drain a single pool. Only
the built-in GITHUB_TOKEN gets its own allowance, and that token cannot write user-owned boards,
which is why the tracker steps carry the PAT at all. So a red pulse run at the same minute your
own gh commands are refused is one budget seen from two places — see the entry above for how to
read the real gauge.
What spends it, measured on 3 September: GraphQL prices what a query could return.
gh project item-list --limit 100 asks for a hundred field values on every item, so a page
costs about 100 points whatever the board holds, and gh project view plus field-list
cost about 104 more. Every board write that first found its row therefore paid about 210
points, and a pulse refresh about 950. Twenty learners submitting three times in one hour would
have been far more than the hour holds, with the tracker step refusing mid-session (the reply
still posts; the row is what is lost). PR #197 replaces both gh calls with queries that ask for
exactly the board's fields: a write is then about 20 points and a pulse refresh about 140. Even
so, run seeds and map regenerations in a different hour from a session.
Fix: run seeds, map regenerations and other bulk jobs outside session hours, and let the
guards work. Every board script reads the remaining budget from the response headers
(boards.graphql_budget()) before it starts and refuses cleanly with the reset time rather than
dying halfway through an update. A red pulse run carrying this message is the guard doing its
job, not a broken workflow — the next cron tick, every six hours, picks it up.
Wiki, not docs. Anything that should be reviewed, versioned with the code, or published to the
docs site belongs in docs/ instead —
see Wiki Conventions. · Report a problem
When it breaks
Reference
The cohort
Meta
In the repo