Troubleshooting
Start here:
oasis-agent doctor # what is installed, and anything that looks wrong
oasis-agent --show-config # every resolved value, and which layer supplied itBetween them these answer most questions about why the agent is behaving differently from what you expected.
Startup
--base-url is required
--base-url has no default. Configure it once, or supply it every run.
oasis-agent setup # save it to ~/.oasis/config.json
export OASIS_BASE_URL=http://10.0.0.1:8080 # or set it in the environment
oasis-agent --base-url http://10.0.0.1:8080 # or pass it explicitlyAn unknown config key fails startup
This is deliberate. A typo fails loudly rather than producing a run that quietly ignored your setting.
Config-file keys mirror flag names in snake_case: base_url, not base-url or baseUrl. oasis-agent --show-config lists the ones that resolved.
The wrong version runs
oasis-agent doctorCommon causes:
| Cause | Fix |
|---|---|
Another oasis-agent earlier on PATH | which -a oasis-agent |
~/.local/bin not on PATH | Add it, or set OASIS_INSTALL_DIR |
| A hand-replaced launcher | Yours is respected and never overwritten. Check what it execs |
versions/current names a version that is not installed | oasis-agent install <version> |
A capability pack's tools are missing
Packs are opt-in. Check the modules key:
{ "modules": { "ethercat": true } }oasis-agent --show-config reports which modules a run actually loaded. Startup also prints a line per pack as it registers.
Permissions
An unattended run stalled
Almost always a hard-stop tool. EtherCatWriteIo, ModbusWrite, OpcUaWrite and their siblings prompt in every mode, including dangerous, and --skip-permissions does not waive them.
There is no flag that changes this. Restructure the pipeline so a human answers, or so it does not perform a physical write. See Permission Model.
auto mode is still asking
auto means "nothing routine is asked inside the working directory". These always prompt:
- Paths outside the sandbox root
- Anything under
/etc,/dev,/proc,/sys,/root
If the agent should be writing somewhere else, set --cwd to include it rather than escalating the mode.
A background agent shows blocked
It met something it may not do, stopped, and saved state. It did not guess.
oasis-agent agents # see what it is waiting on
oasis-agent --resume <id> # pick it up where you can answerDispatch with --mode auto next time if the work is routine and confined to a directory.
Performance
Turns are slow
Check prefix-cache reuse. Steady state should be 94–100%; a turn boundary at 100% costs 134 ms, at 0% it costs 17.2 s.
| Symptom | Likely cause |
|---|---|
| Slow on the first turn only | Normal. One cold prefill |
| Slow on every turn | The prefix is changing between turns |
| Slow after a config change | Expected once. It should settle |
Things that change the prefix: enabling or disabling a capability pack, adding or removing an MCP server, an MCP server that connects intermittently, --cwd-hint.
An intermittent MCP server is the one that hides. It reshapes the tool schema on every run it misses. Set "required": true so the run fails instead.
A long conversation slows down
That is compaction. When it fires, the reprocessing phase pays a cold prefill of the whole compacted prompt.
Reduce how often it happens by delegating bulk reading to a subagent. Only the summary crosses back into the parent's context.
Cold start is slow
Process start to first inference request should be ~24 ms. If it is not, the /props probe is the usual cost:
oasis-agent --context-window 120000 --max-prompt-tokens 111808 --no-probe -p "…"--no-probe is implied when both window values are given explicitly.
MCP
A server's tools never appear
By default a server that fails to connect is skipped and the run continues. Read the startup output. It reports a failure per server.
Set "required": true to fail startup instead.
A tool has an unexpected name
Look for a tool renamed message at startup. Two names that sanitise to the same string collide and are disambiguated with a hash suffix. The model sees the renamed one.
A collision usually means two config entries that wanted to be the same server.
OAuth fails on a headless machine
The browser flow needs a browser. A headless run with no cached token fails with instructions rather than hanging.
# Once, on a machine with a browser
oasis-agent --mcp-config <path> --mcp-loginThen copy ~/.config/oasis-agent/mcp-tokens.json to the headless machine, or use static headers with ${VAR} expansion instead.
A header token is not being sent
${VAR} expands from the environment, and an unset variable expands to empty with a warning rather than failing. Check the warning at startup, and check the variable is exported into the agent's environment, not just set in your shell.
Checks and audit
A check reports error or not_applicable
Neither is a failure and neither is a pass. Both carry a reason: a missing tool, a probe that produced no number, a command that would not start, or a check that does not apply to this subject.
Both leave the exit code at 0, deliberately. A pipeline that went red because a tool was missing would teach its owners to stop reading it.
no profile named "…"
The error names every profile the build has. Profiles are all plus one per compiled-in module, so a build without the OPC UA pack has no opc-ua profile.
oasis-agent audit --list-profiles
oasis-agent check --list-modulesTwo audit reports differ on every run
They should not. Reports are byte-identical apart from one generated: timestamp line.
If more than that line differs, something on the machine changed, which is what the property is for. Diff them.
Control protocol
A method answers unsupported
Either it is one of the four host-mutating methods and the server was not started with --allow-host-mutations, or it is not in this build.
Read features[] from the hello response. It lists exactly what the build answers.
frame_too_large
A frame exceeded 16 MiB. This is a typed error, not a disconnect, so you know which frame was rejected. Page long transcripts with transcript.get rather than requesting them whole.
A long poll returned nothing
That is a normal outcome, not an error. session.poll with waitMs > 0 parks until an event arrives or the deadline passes. Re-poll from the nextSeq you were given.
A gap event arrived
Events were dropped from the ring because the client fell too far behind. Re-read from the sequence number the gap reports, or fetch the transcript with transcript.get.
EtherCAT
EtherCatScan fails with a raw socket permission denial
The binary is missing CAP_NET_RAW and CAP_NET_ADMIN. install and update normally grant these, so this means the install ran somewhere it could not get root: cron, a container build, a CI runner, or a host with no sudo or no setcap.
The error names the exact file and command. Two traps make this worse than it looks if you work it out yourself instead:
setcapon~/.local/bin/oasis-agentdoes nothing. It is a#!/bin/shlauncher, and Linux ignores file capabilities on interpreted scripts. The command reports success and changes nothing. Target the versioned binary under~/.oasis/versions/<version>/.- A running process cannot pick them up. Capabilities are granted at
exec, so retrying the tool in the same session fails identically no matter whatgetcapnow reports. Restart the agent.
sudo setcap cap_net_raw,cap_net_admin+eip \
~/.oasis/versions/$(cat ~/.oasis/versions/current)/oasis-agent
# then restart the agentRe-running the installer from a terminal fixes it too. oasis-agent doctor shows what the process holds and what the binary carries. When those two disagree, a restart is the fix rather than another setcap.
Bus acquisition is refused
If capabilities are present, check --ethercat-acquire-bus. It is a restriction, not a grant. If it names eth1, every other interface is off limits.
product_name is null
Expected without configuration. Vendor ids resolve from an embedded register; product names need vendor ESI XML.
{ "ethercat_catalogue": "/path/to/esi" }The files are usually already on the engineering PC. TwinCAT keeps its library under Config/Io/EtherCAT.
Outputs are still energised
A live I/O session holds outputs between turns. It appears in /jobs, so you can stop it yourself without the agent's cooperation: k to kill it, or ask the agent for EtherCatStopIo.
Sessions
A conversation will not resume
Only clean turns are persisted. A turn that failed leaves the last known-good file intact, so the conversation resumes from before the failure rather than into a poisoned context.
oasis-agent sessions --limit 50Confirm the run was not started with --no-session.
Getting more detail
| Source | Contents |
|---|---|
oasis-agent doctor | Installation state and setting provenance |
oasis-agent --show-config | Every resolved value and its layer |
<id>-agent.err | A background agent's diagnostics |
<id>-agent.jsonl | A background agent's full event stream |
~/.oasis/audit.jsonl | Every file write, actor-stamped |
Still stuck? Report a mistake in these docs, or raise it through the support portal.