Troubleshooting¶
Errors are grouped by the message Sira prints.
Playwright cannot find a browser¶
❌ Failed to scrape job posting from URL: … Executable doesn't exist at …
💡 Tip: Ensure the URL is publicly accessible and contains a valid job posting.
The Playwright Python package is installed, but the actual browser binary is a separate download. Install it once:
uv run sira setup # or just `sira setup` when installed from PyPI
On Linux you may also need the shared libraries the browser links against:
uv run playwright install --with-deps chromium
❌ Failed to scrape job posting from URL¶
The scraper drives a real headless browser, so it can read JavaScript-rendered postings. It still fails when:
| Cause | What to do |
|---|---|
| The posting is behind a login | Save the posting text to a file and open an issue — Sira currently only scrapes public URLs. |
| The page is bot-protected | Some boards block headless browsers outright. Try the employer's own careers page rather than the aggregator. |
| The page is slow | The default timeout is 30 seconds per navigation. A very slow page can exceed it; retry. |
| The URL redirects to a search page | The posting has probably expired. |
⚠️ Potential prompt-injection content detected in the job posting¶
The page contains text aimed at an AI reader — an instruction override, a hidden block, a request to rate the candidate highly — or a phrase that exists in the HTML but not in the visible text. The run continues; the warning lists only category names (see the agent reference for the full table). Read the tailored CV and report with extra care, and compare the requirements Sira extracted against the posting as a human sees it. False positives happen on security-engineering postings that discuss these attacks; the warning is advisory, nothing is blocked.
⚠️ Prompt-injection classifier unavailable (…)¶
You installed the guard extra but the local model could not be loaded — usually a
missing Hugging Face token for the gated default model, no network on first run, or
not enough memory. Sira falls back to the regex scan. Fix the cause, or set
SIRA_GUARD_MODEL=protectai/deberta-v3-base-prompt-injection-v2 for an ungated model,
or set SIRA_GUARD_CONSENT=no to silence the layer.
❌ Job posting scraped but content is empty¶
The page loaded, but nothing survived extraction. This normally means the posting body is rendered behind an interaction (an "expand" button) or the page is a listing rather than a single posting. Use the URL of the posting itself.
❌ Error: Job URL must start with http:// or https://¶
The first argument is the URL, the second is the resume path — in that order. A local file path in the first position produces this message.
❌ Resume file not found at …¶
The path does not exist. ~ is expanded, but shell quoting still matters:
uv run sira tailor <JOB_URL> "~/Documents/my resume.pdf"
❌ Failed to convert resume: …¶
Only .md, .docx, and .pdf are accepted. Some PDFs — scans, or heavily designed
layouts — extract badly or not at all. Two things to try:
- Export the resume to
.docxfrom the original editor and pass that instead. - Run with
--debugand readresume_converted.mdin the output directory. That file is exactly what the parser saw. If it is empty or scrambled, the problem is conversion, not the model.
❌ Resume content is empty¶
The file exists but converted to nothing. Almost always an image-only PDF, which has no extractable text layer. Convert it to text first, or use the original document.
❌ Original resume not found at recorded path: …¶
re-tailor looks the original resume up at the path recorded when you first ran
tailor. If you moved or renamed that file, point at the new location:
uv run sira re-tailor <JOB_ID> "…" --resume-path ~/Documents/resume.pdf
❌ Job not found: <id>¶
The job ID is the UUID printed at the end of a successful tailor run, and it is
looked up in the memory database. Since 1.5 that database
is shared across working directories; before 1.5 it was memory/resume_memory.sqlite3
relative to where you ran tailor, and Sira moves such a file into the data directory
the first time it runs from that place. If the ID came from a run in another directory
on an older release, run sira once from that directory so its database is moved.
❌ No job posting content stored for this job¶
The job row predates the column that stores the posting text, so re-tailor has
nothing to work from. Re-run tailor on the original URL.
Authentication errors from the model provider¶
AuthenticationError: Incorrect API key provided …
Each provider reads its own environment variable — see Models and providers. Two cases catch people out:
- No key at all. Agents are built at import time with a placeholder key so that importing Sira never fails. The error only appears at the first real call.
--fastwith a non-OpenAI model. The fast tier stays onopenai:gpt-5-nano, so anOPENAI_API_KEYis still required. Drop--fastto use a single provider.
Ollama: connection refused, or a missing base URL¶
PydanticAI has no default endpoint for Ollama. Export it explicitly:
export OLLAMA_BASE_URL=http://localhost:11434/v1
Then confirm the daemon is up (ollama list) and the model is pulled
(ollama pull llama3).
The audit keeps failing¶
The auditor rejects a draft that invents facts, leans on clichés, or drops hyperlinks. Give the loop more room:
uv run sira tailor <JOB_URL> <RESUME_PATH> --write-attempts 3 --review-iterations 2
If it still fails, read the report's Audit Summary — the reason is usually specific,
and re-tailor with an instruction addressing it works better than more retries.
The terminal output looks garbled¶
The live dashboard and some plain print() calls in the workflow can interleave in an
interactive terminal. The run is unaffected; only the drawing is. Use --verbose for
clean streaming output, or pipe the output — in a non-TTY the dashboard degrades to
line-by-line logging.
The run is slow or expensive¶
Start with --fast, then tune:
uv run sira tailor <JOB_URL> <RESUME_PATH> \
--no-quality-gate --write-attempts 1 --review-iterations 0
The trade-offs behind each flag are in Controlling cost.
Nothing here matches¶
Run with --verbose to see each agent's input and output as it streams, and open an
issue at Tiqni/sira/issues with that output.