Logs and bug reports
This page shows what cora and cora-mcp can tell you about a problem, and where they write it. Reporting a problem says where to send a report.
What a bug report needs
Section titled “What a bug report needs”npx cora info prints what a bug report needs, without launching anything:
- which
coraran and why, and the cora-mcp releasecora mcpwould run; - Node.js, the operating system, the package manager, the CI provider, the coding agent that runs
cora, and the one whose variables your environment carries, as an IDE’s terminal carries Claude Code’s; - the project’s config and its hash, and where its state and logs are;
- where your user config is, whether it was read, and what it ignored;
- the CORA service
corareaches, and its request timeout; - the Playwright packages and browsers
corawould use, and axe-core’s version; - which of the environment variables
corareads are set.
Paste its output into the report, or attach npx cora info --json. Its reference entry says which values it prints.
cora info reports where the project’s Playwright expects its own Chromium, and the browsers in Playwright’s download directory. npx playwright install --list lists the browsers of every Playwright installation on the machine.
Checking the account, the scans and the fixes
Section titled “Checking the account, the scans and the fixes”npx cora status shows whether your CORA account is valid, the project’s newest scans, and where each issue stands while CORA’s fixer works on it:
Account: valid, Acme, plan team, expires in 23 hours
Scans: 2 recent 20261006T170903123Z-a1b2c3d4: 1 target, 1 issue, from mcp, 2 minutes ago 20261006T170201123Z-k3j9x2ab: 11 targets (1 not scanned), 14 source files, 10 issues (1 needs review), from cli, 9 minutes ago
Fixes: 1 in progress, 2 not attempted, 1 done in progress: rule axe/button-name, page http://localhost:5173/settings, element button.icon, last result still-failing, 2 attempts not attempted: rule axe/color-contrast, page http://localhost:5173/, element a.footer-link not attempted: rule axe/image-alt, page http://localhost:5173/, element img.hero done: rule axe/label, page http://localhost:5173/signup, element input#email, last result fixed, 1 attemptAt a terminal, the scans and the fixes line up in columns under their headings where they fit its width, and a mark stands beside each verdict, such as ✓ beside valid, where the terminal draws one. With screenReader on, each scan and each fix stays one labeled line, as above.
- Account is
valid, with the organization, its plan and when the token expires, ornot validwith the error that says why, such asaccount.missingbefore you sign in. It checks the account without renewing it, and exits 0 either way. A saved token that has expired reads asvalid, token expired, renews on next use, since the next command that needs the account renews it. - Project reads
not foundwhen you runcora statusoutside a project. The scans and fixes it then lists are those in.cora/in the folder you run it in (Scanning without a project). - Scans lists the five newest results files, from
cora scanand from cora-mcp’s scans, each by its run ID, the name of its results file in.cora/runs/. Each gives the targets it covered, the source files it covered where its results cover some, the issues it found, what ran it and when, with the targets and the source files not scanned beside their counts. When.cora/runs/holds more, a last line counts them, as inand 12 more in .cora/runs. - Fixes lists each issue a coding agent’s scans found, by where it stands:
in progresswhileverify_fixhas not found it fixed;not attemptedbefore any fix of it was checked;escalatedonce it was handed to a person after three attempts without a fix;doneonceverify_fixfound it fixed.
The fixes list empties as summarize_fixes reports the issues. A file this release cannot read, such as one another release wrote, is left out with a warning naming it: run file skipped or loop record skipped. A fix of an issue whose loop record is left out fails in verify_fix and summarize_fixes with mcp.loop-unreadable, which names the file to delete.
npx cora status --json prints whether the account is valid, the scans and the fixes as one JSON object, for scripts and status lines. Its versioned format, cora-status, is named by its format and version fields. cora status reads .cora/ wherever your stateDirectory moves it, in the project or outside one.
Seeing more
Section titled “Seeing more”Each logging setting is a key of your user config, which applies to every command you run:
log.level: how much CORA writes, fromtracetosilent;log.file: whether it also writes a log file, and where;log.format:humanlines or JSON Lines on stderr;log.filesKept: how many log files of each kind are kept;color: whethercoracolors its stderr.
For example, to log at info, with a log file, in every project:
{ "log": { "level": "info", "file": true }}The global options set them for one command, such as --debug, which logs at debug and writes a log file. Where you cannot change the command, such as in CI, each one’s CORA_LOG_* variable sets it. Which value wins gives their order.
- A command that writes a log file prints its path,
Log: <path>, as its last line, after a blank line, whether it succeeded or failed.-qand--log-format jsonleave that line out, with the summary. --log-filetakes an optional path from the next argument. Write--log-file=<path>, or put--log-filelast, when a target follows it.- CI debug mode logs at
debugwhere no flag or variable sets the level, whatever your user config says. Re-running a GitHub Actions job with debug logging (RUNNER_DEBUG=1) turns it on, as doessystem.debugin Azure Pipelines.
Each line on stderr reads <time> <LEVEL> <message> key=value .... With --log-format json, each is a JSON object instead.
Log files
Section titled “Log files”A log file holds every record at the chosen level as JSON Lines. Each line is one object, with @timestamp, level, message and the record’s fields under properties. Its first records say what may be in the file. The next describe the run: the cora, Node.js and Playwright versions, the browser, the config file and the log level, and for cora-mcp the agent’s client.
Log files live in .cora/logs/ in the project, or outside a project in the folder you run cora in, or wherever your stateDirectory moves .cora/. In a folder CORA cannot write, a log file you ask for is not written, and the command warns log file not opened, naming the file.
| File | Written by |
|---|---|
cli-<time>-<pid>.log |
A cora command, when you ask for a log file |
mcp-<time>-<pid>.log |
cora-mcp, when you ask for a log file |
hooks-<session>.log |
The plugin’s hooks, always, one for each coding-agent session |
crash-<time>-<pid>.log |
cora or cora-mcp, when it hits a bug |
CORA keeps the newest files of each kind, and deletes older ones. log.filesKept sets how many. A log file at a path you name is never deleted.
Crash files
Section titled “Crash files”When cora hits a bug, it writes a crash file next to the log files, and prints its path:
error[internal.unexpected]: cora hit an internal errorhint: Send this crash file to cora@vispero.com: `.cora/logs/crash-20261006T170501123Z-4242.log`A crash file opens like a log file, with the latest of each record that describes the run:
cora started: thecoraand Node.js versions, the platform, the project and the log level;launch decided, forcora: which copy ofcoraran the command, and why;config loaded: the config file and its hash;browser launched: the Playwright and browser versions;version alignment, for cora-mcp: which release served the agent, and why;client identified, for cora-mcp: the agent’s client.
Its last 200 other records follow, at debug whatever level it was printing, then the error. When cora-mcp hits a bug in a tool, it writes a crash file the same way, gives its path in the tool’s error, and keeps serving. Send the file with your report.
In a folder CORA cannot write, the crash file is not written, and the error says cora hit an internal error and could not write its crash file, or cora-mcp in place of cora. Report the command you ran, or what the agent was doing, instead.
What logs contain
Section titled “What logs contain”CORA removes credentials before anything reaches stderr, a log file or a crash file:
- passwords and tokens in URLs;
Authorizationand cookie values;- tokens that look like JWTs or npm tokens;
- the cookie and local-storage values of the storage-state file;
- the values of environment variables whose names contain
TOKEN,SECRET,PASSWORDorKEY, and where such a value is a file’s path, that path as CORA names it from the current directory or the project root; - the credentials in the URL of a proxy variable.
CORA removes the storage-state file’s values and the variables’ values only when they are 8 characters or more, since a shorter one would match ordinary text.
CORA finds a credential even where another tool’s terminal colors split it, such as an error a library printed in color, in its text or in the address of a terminal hyperlink; the text that held it is then written without its colors and links.
A results file removes less: the passwords in its URLs, and the URL parameters that only ever carry a credential, such as token. It holds each element’s markup as the engines report it, so a secret the page shows can reach it.
Your user config
Section titled “Your user config”cora and cora-mcp read your user config as they start. A release ignores what it does not take in the file, rather than failing, and warns on stderr, naming the file:
user config setting ignored, for one key, with the key and what is wrong with it. That setting comes from the next source down.user config ignored, for the whole file. Every setting then comes from the next source down.
What a release does not take says what each warning covers.
npx cora info shows the same in its User config section: the file’s path, whether it was read, and each thing it ignored, as in Ignored log.rotate: a key this release does not know. cora-mcp warns in its client’s log, which Seeing cora-mcp’s stderr shows how to read.
A process that hands over to another copy reads the file too, so a warning can show twice. A global cora hands over to the project’s, and cora-mcp to the project’s release.
Playwright’s own logs
Section titled “Playwright’s own logs”DEBUG prints Playwright’s own diagnostics on stderr, and DEBUG_FILE writes them to a file instead:
DEBUG=pw:api,pw:browser npx cora scan$env:DEBUG = "pw:api,pw:browser"npx cora scanFor cora-mcp, set DEBUG in the MCP entry’s env: pw:api,pw:browser for Playwright’s diagnostics, and pw:mcp:* for playwright-mcp’s.
Playwright variables CORA ignores
Section titled “Playwright variables CORA ignores”cora and cora-mcp unset some of Playwright’s variables, such as PWDEBUG, since each would change what a scan finds. The environment variable reference lists them, and they still apply to your own Playwright tests.
Seeing cora-mcp’s stderr
Section titled “Seeing cora-mcp’s stderr”cora-mcp logs on stderr, which the agent’s client keeps:
claude --debug=mcp writes MCP diagnostics, each server’s stderr included, to the session’s debug log, ~/.claude/debug/<session-id>.txt. --debug-file <path> writes the debug log to that path instead. Give the filter with =, as shown.
/mcp shows whether the server connected.
codex -c log_dir=<dir> writes a plain-text log, <dir>/codex-tui.log. There, each line cora-mcp writes on stderr follows MCP server stderr (npx):.
Without log_dir, Codex keeps its diagnostics in its own stores, rather than a text file.
In any client, cora-mcp writes a log file of its own when your user config’s log.file, or CORA_LOG_FILE in its entry, asks for one, as More detail from cora-mcp shows.
More detail from cora-mcp
Section titled “More detail from cora-mcp”At its default log.level, cora-mcp’s stderr shows which release serves the agent and why, the client, its settings, the config, the browser it launched, and a browser tool’s own error. A tool that fails is logged at warn, and a bug in cora-mcp at error, with its crash file. Each tool call is logged at debug.
cora-mcp takes no logging options. Set the logging settings in your user config, which reaches cora-mcp under every client and in every project:
{ "log": { "level": "debug", "file": true }}The plugin’s entries name no logging variable. Under Codex, one set in your shell never reaches the plugin’s cora-mcp, and Claude Code’s docs do not say whether it does. Your user config reaches cora-mcp under both. In an entry you write yourself, the settings’ variables in its env win over your user config for that entry:
{ "mcpServers": { "cora": { "type": "stdio", "command": "npx", "args": [ "--yes", "--prefer-offline=false", "--fetch-retries=0", "--fetch-timeout=3000", "@vispero/cora-mcp@<version>" ], "env": { "CORA_LOG_LEVEL": "debug", "CORA_LOG_FILE": "1" } } }}[mcp_servers.cora.env]CORA_LOG_LEVEL = "debug"CORA_LOG_FILE = "1"Either change applies when the client next starts the server. With a log file asked for, cora-mcp writes mcp-<time>-<pid>.log in the project’s .cora/logs/.
For an npx --no cora mcp entry, the same variables work. Or put cora’s own options before mcp, as in npx --no cora --log-level debug mcp: they pass on to the release it runs.