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. In a terminal, first-run setup asks for it instead of failing. This message is what a non-interactive run sees: CI, a container build, a piped install. Note that check and audit need no endpoint at all.
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.
404 page not found on every message
The address is being sent one path segment too deep, usually /v1/v1/chat/completions. The server is running, the banner looks right, and nothing works.
oasis-agent --show-config # check what base_url resolved tobase_url should end at the host, or at a single /v1. Setup saves the path that answered, so re-running oasis-agent setup also corrects it.
The prompt does not fit the context window
A warning at startup naming the prompt size, the window, and the setting to change.
The system prompt and the tool schemas are sent on every request and do not shrink, so compaction cannot help: it works on the conversation, and this is the floor under a conversation of length zero. With ollama's 4096 default and the industrial packs enabled, the first turn opens over budget and the server truncates what it receives.
Two ways out:
- Raise the server's context length. First-run setup will size it for the machine, or set
OLLAMA_CONTEXT_LENGTHyourself. - Turn off capability packs you are not using, which shrinks the tool set. See Capability Packs.
It is a warning and not a refusal. The estimate is approximate and the run proceeds.
The first message after setup fails
Setting the context length restarts the model server, and a restart takes a moment. Setup waits for it and says so if it does not come back in time. The install is complete and the config is written either way; wait a few seconds and try again.
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 conversation forgets things it was told
Not compaction working, but compaction never firing. If the agent resolved a context window much larger than the server actually serves, its compaction threshold sits above anything it can reach, so instead of compacting at the right moment it sends ever-longer prompts to a server that silently truncates them.
oasis-agent --show-config # what window did it resolve, and from whereollama defaults to 4096 tokens. Raise it with first-run setup, or set --context-window to the real value.
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.
The figures above assume a large window. On a window of roughly 16k or less, the prompt budget is half the window rather than the window less the response reserve.
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.
The interface does not exist
The error names the interface it could not find and lists the wired NICs on the machine. Only wired NICs are listed. EtherCAT is raw layer 2, so loopback, bridges, virtual interfaces, wireless and VPN tunnels are never candidates. That includes the Cloud Link interface, which cannot carry layer-2 frames however healthy the tunnel is.
A scan against a name that does not exist no longer costs the process its bus. Correct the name and scan again in the same session.
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.