Guides / Java / Errors and troubleshooting
Java errors and troubleshooting
Everything the SDK throws is a Kosa8Exception, and an error from the
daemon keeps the daemon's own words: what went wrong, and what to do about it. This page lists each
class, when it is thrown and how to handle it, then the problems you are likely to meet, from
symptom to fix.
This page describes SDK 0.1.2 (com.kosa8:kosa8:0.1.2 on Maven Central). The
capture and mount messages, which 0.1.2 changed or added, were printed by 0.1.2 built from the v0.1.2 tag (commit 14e5fc6) with mvn install, because Maven Central was still answering 404 for 0.1.2 while it was being published. Each
message in a terminal block was printed by a Java program on OpenJDK 21.0.12.1, against kosa8
daemon 0.9.36 on an Apple silicon Mac (macOS 26.0.1). The messages that 0.1.1 added or changed (the
failed rewind, the lock timeout, capture(true), exec with env, a second
writeStdin, a bad mount) came from 0.1.1, built from its release tag just before it was
published; the published jar carries the same messages (checked in its class files). The rest came from 0.1.0 from
Maven Central, on code paths 0.1.1 did not change; the run, exec, stdin and timeout ones were
re-run on 0.1.1 and printed the same. What changed between the two versions is listed
at the end. AuthException,
PolicyException, ApprovalRequiredException and
UnsupportedException were not produced: that would have meant installing an org
policy or a remote worker on a shared test machine. Their sections are from the SDK's source, and
say so. The locked-screen rewind failure is quoted from the Go SDK's run of the same daemon.
What this is, in plain words
When something goes wrong, the SDK throws an exception. Java has two kinds: checked
exceptions, which the compiler makes you catch or declare, and unchecked ones, which it does
not. All of this SDK's exceptions are unchecked: your code compiles without any
try/catch, and you catch only what you want to handle.
Each exception says what happened in its message. When the daemon refused something, the message
also carries the daemon's advice in brackets, and the same two parts are available separately as
daemonMessage() and remediation().
One thing is not an exception: a command that runs and exits with a non-zero code. That
is a normal result; check result.exitCode() or result.ok().
The hierarchy
All classes are public static classes nested inside com.kosa8.Kosa8Exception,
so you write Kosa8Exception.NotFoundException, or import them individually
(import com.kosa8.Kosa8Exception.NotFoundException;).
java.lang.RuntimeException unchecked └─ Kosa8Exception anything this SDK throws; used as is for client-side checks ├─ ConnectionException the daemon could not be reached ├─ ApiException the daemon answered with an HTTP error (any status, e.g. 500) │ ├─ BadRequestException 400 │ ├─ AuthException 401 │ ├─ PolicyException 403 │ │ └─ ApprovalRequiredException 403 that a signed approval would lift │ ├─ NotFoundException 404 │ ├─ ConflictException 409 │ └─ UnsupportedException 501 ├─ StreamException a run, exec or attach stream ended with an error, or broke ├─ CheckpointException checkpoint bookkeeping: none to rewind to, bad name, failed restore └─ TimeoutException a request ran out of time
Kosa8Exception.TimeoutException is not java.util.concurrent.TimeoutException
(which is checked). If you import both, refer to the SDK's by its qualified name. Likewise,
Kosa8Exception itself extends RuntimeException, so a
catch (RuntimeException e) placed first will swallow it.
Fields
| Accessor | On | Meaning |
|---|---|---|
getMessage() | all | For a daemon error: "<error> (<remediation>)", the way the CLI prints it; just <error> when there is no remediation; "request failed with HTTP <status>" when the body had no text. |
status() | all | The HTTP status for an ApiException; 0 for everything else (the daemon did not answer with an error status). |
daemonMessage() | ApiException, StreamException | The daemon's error text (or message if there is no error), verbatim. For a stream, the error frame's text. null otherwise. |
remediation() | ApiException | The daemon's advice, or null. |
method(), path() | ApiException, ConnectionException, TimeoutException | The request that failed, as POST and /kosa8/v1/sandboxes/x/run. null on the others. |
body() | ApiException | The decoded response body: a Map for JSON, a String otherwise. |
getCause() | ConnectionException, some CheckpointExceptions and plain ones | The underlying exception, as java.net.SocketException, or the restore failure inside a failed rewind. |
stdout(), stderr() | StreamException | Output produced before the stream ended, decoded as UTF-8. Never null. |
approval() | ApprovalRequiredException | The daemon's refusal as a map: why, who may sign, how to request one. |
The program that printed the messages on this page used this helper:
static void show(String what, Kosa8Exception e) {
System.out.println(what + ": " + e.getClass().getName().replace("com.kosa8.", "") + " status=" + e.status()
+ " method=" + e.method() + " path=" + e.path() + "\n message: " + e.getMessage()
+ "\n daemonMessage: " + e.daemonMessage() + "\n remediation: " + e.remediation());
}
try { k.deleteSandbox("no-such-sandbox"); } catch (Kosa8Exception e) { show("delete missing", e); }
Each class
ConnectionException
When: the request never reached a daemon: no socket file, nothing listening, a socket path too long for the operating system, a worker that does not answer within the 30-second connect limit, or a reply that was not HTTP.
no daemon: Kosa8Exception$ConnectionException status=0 method=GET path=/kosa8/v1/health message: kosa8 daemon unreachable at unix:///tmp/no-daemon-here.sock: SocketException: No such file or directory (is kosa8 installed and its daemon running? start it with `kosa8 daemon start`) cause: java.net.SocketException: No such file or directory
Handle: start the daemon or fix the address. The hint in brackets is added when the cause looks like "nothing there". Nothing was done, so it is safe to retry once the daemon is up.
ApiException (any other status)
When: the daemon answered with an HTTP status of 400 or more that has no subclass of its
own, mostly 500. kosa8 0.9.36 uses 500 for some "not found" cases, so these are not
NotFoundException:
start missing: Kosa8Exception$ApiException status=500 method=POST path=/kosa8/v1/sandboxes/no-such-sandbox/up message: no such sandbox: no-such-sandbox (run `kosa8 doctor`; check ~/.kosa8/log/) restore missing: Kosa8Exception$ApiException status=500 method=POST path=/kosa8/v1/snapshots/no-such-snap/restore message: no such snapshot: no-such-snap (list snapshots with `kosa8 snapshot ls`)
It is also what a sandbox that fails to boot looks like on a busy machine:
Exception in thread "main" com.kosa8.Kosa8Exception$ApiException: guest not ready on vsock port 1024 after 25s (run `kosa8 doctor`; check ~/.kosa8/log/) at com.kosa8.Kosa8Exception.fromResponse(Kosa8Exception.java:158) at com.kosa8.Transport.json(Transport.java:262) at com.kosa8.Kosa8Client.createSandbox(Kosa8Client.java:142)
Handle: read the message. Catch ApiException to handle every daemon refusal in
one place; the subclasses below are all ApiExceptions.
BadRequestException (400)
When: the daemon refused a value, most often an egress rule.
bad egress: Kosa8Exception$BadRequestException status=400 method=POST path=/kosa8/v1/sandboxes message: egress allow "*.com": com is a public suffix, under which anyone can register a name, so the wildcard would admit strangers' hosts; allow a domain below it, as in *.example.com remediation: null
Handle: fix the input; retrying the same request fails the same way.
AuthException (401)
When: a remote worker rejected the bearer token, or none was sent. (From the source; not produced for this page.) The token is never sent over a unix socket, so this comes only from a worker.
Handle: check the token. A common cause: KOSA8_TOKEN is read only when the host
also came from KOSA8_HOST. If your code calls builder().host(…), it must call
token(…) too.
PolicyException (403)
When: the org policy forbids the action: a registry that is not allowed, an egress rule wider than the policy permits, and so on. (From the source; not produced for this page.)
Handle: the message names the policy and the rule. Retrying will not help; change the
request or the policy (kosa8 policy show).
ApprovalRequiredException (403)
When: a 403 whose body carries an approval object with a why string:
the action is allowed once someone signs for it. It extends PolicyException, so catch it
first. (From the source; not produced for this page.)
try {
k.pull("ghcr.io/acme/tool:1");
} catch (Kosa8Exception.ApprovalRequiredException e) {
System.out.println("needs approval: " + e.approval().get("why"));
// once signed: k.pull("ghcr.io/acme/tool:1", Options.Approval.of(signature));
}
NotFoundException (404)
delete missing: Kosa8Exception$NotFoundException status=404 method=DELETE path=/kosa8/v1/sandboxes/no-such-sandbox message: no such sandbox: no-such-sandbox (list sandboxes with `kosa8 sandbox ls`) run missing: Kosa8Exception$NotFoundException status=404 method=POST path=/kosa8/v1/sandboxes/no-such-sandbox/run message: no such sandbox: no-such-sandbox (list sandboxes with `kosa8 sandbox ls`) delete snap missing: Kosa8Exception$NotFoundException status=404 method=DELETE path=/kosa8/v1/snapshots/no-such-snap message: no such snapshot: no-such-snap (list snapshots with `kosa8 snapshot ls`)
Handle: in clean-up code, a NotFoundException from a delete usually means "already
gone" and can be ignored. getSandbox and sb.info() never throw this: they
return null.
ConflictException (409)
dup: com.kosa8.Kosa8Exception$ConflictException 409: sandbox doc-java-snap already exists (choose another name, or remove the existing sandbox with `kosa8 sandbox rm NAME` (`kosa8 sandbox ls` lists them))
Handle: pick another name, or reuse the existing sandbox.
UnsupportedException (501)
When: the daemon (or this platform) does not support the operation. (From the source; not produced for this page.)
StreamException
When: run, exec or attach started streaming and then
ended with an error frame, broke mid-stream, sent a line that is not a valid frame, or ended without
a final frame. Because the daemon reports some failures inside the stream rather than as an HTTP
status, these are stream errors too, with status() 0:
unpulled: com.kosa8.Kosa8Exception$StreamException status=0: image "docker.io/library/python:3.12-alpine" not found in engine: image "docker.io/library/python:3.12-alpine": not found exec missing: com.kosa8.Kosa8Exception$StreamException status=0: no such container: nope
Handle: e.stdout() and e.stderr() hold whatever was printed before
the failure; e.daemonMessage() is the error frame's text. A non-zero exit code is
not a StreamException. execFrames does not throw one for an error
frame either: it hands the frame to your consumer.
CheckpointException
When: client-side checkpoint bookkeeping fails, before or after the daemon is involved:
rewind none: Kosa8Exception$CheckpointException status=0 method=null path=null message: no checkpoints for "never-checkpointed" — take one with checkpoint() or `kosa8 checkpoint never-checkpointed` bad name: Kosa8Exception$CheckpointException status=0 method=null path=null message: invalid sandbox name "../etc"
Also: no checkpoint "X" for sandbox "Y" when rewind(to) matches no id or
label; update the checkpoint store … when the file cannot be written (the
IOException is the cause); a lock that another process holds for longer than the store's
lock timeout (10 seconds unless you built the store with new FileCheckpointStore(path,
Duration)), here with a 2-second limit:
com.kosa8.Kosa8Exception$CheckpointException after 2021ms: timed out after 2s waiting for /private/tmp/…/ck/checkpoints.json.lock; another kosa8 process is holding it
and, most importantly, a failed restore during a rewind:
A rewind whose restore failed. A rewind deletes the sandbox first, then restores the checkpoint under the same name. If the restore fails, the sandbox no longer exists, and the message says so and tells you how to bring it back. To produce one for this page, the latest checkpoint's snapshot was deleted behind the SDK's back before rewinding to it:
failed rewind: com.kosa8.Kosa8Exception$CheckpointException: restore failed and doc-java-011 no longer exists (it was deleted to free its name for the restore): no such snapshot: doc-java-011-ckpt-2 (list snapshots with `kosa8 snapshot ls`) — the checkpoint is intact; recover with restoreSnapshot("doc-java-011-ckpt-2", new Options.Restore().name("doc-java-011"))
sandbox after failed rewind: null
"The checkpoint is intact" is true when the restore failed for a passing reason such as a locked screen. In this artificial case the snapshot itself was gone, so there was nothing to restore. (0.1.0 said the sandbox "is now stopped", which was wrong: it has been deleted.)
On a Mac the usual cause is a locked screen: the daemon answers macOS blocks restoring a VM
while the screen is locked; unlock and retry (as seen from the Go SDK against the same
daemon). Unlock, then run the call from the message:
k.restoreSnapshot("doc-java-demo-ckpt-1", new Options.Restore().name("doc-java-demo"));
The checkpoint records are not changed by a failed rewind, so rewind also works again
once the cause is fixed. getCause() is the original ApiException.
If you give up instead of recovering, clean up by hand. With the sandbox gone,
delete() throws NotFoundException before it reaches the checkpoint
bookkeeping. The sandbox's records stay in ~/.kosa8/checkpoints.json and their snapshots
stay on disk (seen). Delete the snapshots with deleteSnapshot(id, null) for each
sb.checkpoints() entry, then drop the records:
new FileCheckpointStore().update(d -> d.remove("doc-java-011"));
TimeoutException
timeout: com.kosa8.Kosa8Exception$TimeoutException: POST /kosa8/v1/sandboxes/doc-java-guide/run timed out talking to unix:///Users/dhruvit/.kosa8/run/kosa8.sock
When: Options.Run.timeout or the client-wide Builder.timeout passed.
Handle: the command in the sandbox keeps running: after this exception the
sleep 30 container still showed status=running. Clean it up yourself. The
exception carries no output; use the onStdout/onStderr callbacks to keep
partial output.
Kosa8Exception itself
When: the SDK refused before sending anything, or explore could not finish.
Real messages:
bad actor: actor must be human, agent or tool, not "robot"
plain http: refusing to talk to 10.0.0.5:8080 over plain http: the token and every request would cross the network unencrypted. Use https://10.0.0.5:8080 (a worker behind a TLS-terminating tunnel or proxy), or set insecure / KOSA8_INSECURE=1 if this link is already private and trusted
bad scheme: KOSA8_HOST scheme "ftp" is not supported; use http://, https://, tcp:// or unix://
egress: egressAllow already limits the network to the hosts it lists; do not also set egress
explore one: give at least two variants; with one there is nothing to compare
capture(true): capture(true) is not enough: the daemon needs a host file to write the capture to; use capture("/path/to/capture.pcapng")
capture(""): capture needs a host file path to write the capture to
bad mount: mount "/tmp": want host:guest or host:guest:ro
relative: mount "mnt:/work": both paths must be absolute (use Path.toAbsolutePath() for the host side)
exec env: exec does not take env: the container keeps the environment it was started with. Set it at startInteractive, or wrap the command: List.of("env", "K=V", "cmd")
second stdin: stdin of container k3-d6cc9b51 in doc-java-011 was already sent and is closed: the daemon treats one writeStdin body as the whole of stdin. Pass an InputStream to stream input
The first three come from build(). The capture, mount, exec and stdin checks replace
calls that 0.1.0 sent and that then failed or quietly did nothing. (0.1.1 worded the two capture
messages as "host directory"; 0.1.2 says file, which is what the daemon writes.) Others from the
source:
KOSA8_HOST "…" names no host; from explore,
forked N branches for M variants; see listSandboxes() for what was created,
keep X is not one of the branches (…); all of them were kept,
explore interrupted (the thread's interrupt flag is set again) and
explore branch failed: ….
What can escape that is not a Kosa8Exception
| Exception | From | When |
|---|---|---|
java.io.UncheckedIOException | FileCheckpointStore.load() | The checkpoint file exists but cannot be read (permissions). A missing file is fine, and an unparseable one reads as empty. |
| anything | your own CheckpointStore, your callbacks | An unchecked exception thrown by your onStdout/onStderr/onStatus callback or execFrames consumer propagates out of the call and the connection is closed. One exception to that: an IllegalArgumentException (or subclass, such as NumberFormatException) is caught by the frame reader and comes out as StreamException: bad frame from …. (From the source.) |
NullPointerException | arguments | A null sandbox, container or snapshot id (checkpoint calls check the name first and throw CheckpointException instead), or a null variants list for explore. Options arguments may be null; ids may not. |
A handling pattern
try {
Results.Exec r = sb.run("alpine:latest", List.of("sh", "-c", script),
new Options.Run().timeout(Duration.ofMinutes(5)));
if (!r.ok()) log.warn("script failed with exit {}: {}", r.exitCode(), r.stderr());
} catch (Kosa8Exception.TimeoutException e) {
log.warn("still running after 5 minutes; deleting the sandbox");
sb.delete();
} catch (Kosa8Exception.StreamException e) {
log.error("could not run: {} (output so far: {})", e.daemonMessage(), e.stdout());
} catch (Kosa8Exception.ApprovalRequiredException e) {
log.info("needs a signed approval: {}", e.approval().get("why"));
} catch (Kosa8Exception.ApiException e) {
log.error("daemon refused ({}): {}", e.status(), e.getMessage());
} catch (Kosa8Exception.ConnectionException e) {
log.error("is the daemon running? {}", e.getMessage());
}
Order matters: put subclasses before their parents
(ApprovalRequiredException before PolicyException before
ApiException before Kosa8Exception), or the compiler will reject the
later catch as unreachable.
Troubleshooting
Search the page for a few words of the message you see.
| Symptom | Cause | Fix |
|---|---|---|
Maven: prefixes: Path com/kosa8/kosa8/0.1.0/kosa8-0.1.0.jar NOT allowed from central (the .pom downloads, the jar does not) | Newer Maven resolvers check Central's list of top-level folders (/.meta/prefixes.txt) before downloading. Early on 3 November 2026 the list did not yet include the new com/kosa8 namespace, and Maven 3.10.0 refused the jar. Later that day the list included it, and a fresh local repository resolved 0.1.1 with no flags. You can still see this if your local repository or a mirror kept the old list. | mvn -Daether.remoteRepositoryFilter.prefixes=false … once, or add that flag to .mvn/maven.config. Once the jar is in your local repository the flag is no longer needed. |
UnsupportedClassVersionError: com/kosa8/… has been compiled by a more recent version of the Java Runtime (class file version 61.0) | The jar is built for Java 17 (class file 61) and you are running an older JVM. | Run on Java 17 or later. java -version shows which one your build tool uses. |
ConnectionException: … SocketException: No such file or directory (is kosa8 installed and its daemon running? …) | The daemon is not running, or the socket is elsewhere. | kosa8 daemon start, then kosa8 daemon status. If HOME differs between your program and the daemon (a service account, a container, a test harness), pass socketPath(…). After a daemon restart every sandbox is stopped; startSandbox boots it again. |
ConnectionException: … SocketException: Unix domain path too long | macOS limits a socket path to 104 bytes, and the socket is $HOME/.kosa8/run/kosa8.sock. Happens with deep temporary HOMEs in CI. | Use a shorter HOME, or a short symlink to the socket's folder, for both the daemon and your program. |
ApiException: guest not ready on vsock port 1024 after 25s from createSandbox | The new virtual machine did not finish booting in time; seen twice in a row while other programs were booting sandboxes on the same Mac. No sandbox was left behind. | Retry; it succeeded once the machine was less busy. If it persists, kosa8 doctor and ~/.kosa8/log/. |
StreamException: image "…" not found in engine | The image was never pulled into this sandbox. k.pull(ref) pulls into the host's engine, not the sandbox's. | sb.pull(ref) (pullIntoSandbox) first. |
StreamException: no such container: … | Wrong container id, or it exited. | Check sb.containers(). Keep a container alive with a long-running command such as sleep infinity. |
TimeoutException, and the command is still running in the sandbox | A timeout only closes the connection. | Delete or stop the sandbox, or exec a kill in the container. |
createSandbox (or a restore) throws TimeoutException although nothing is wrong | Builder.timeout applies to every request, and boots and restores can take tens of seconds on a busy machine (10–31 s were seen while testing). | Leave the client-wide timeout unset and use Options.Run.timeout per command, or set it well above your slowest boot. |
Kosa8Exception: capture(true) is not enough: … (0.1.0: ApiException 500: capture: no output path) | The daemon needs a path to write the capture to; capture(true) has none. 0.1.1 refuses it before sending; 0.1.0 sent it and got the 500. | capture("/some/folder/traffic.pcapng"): kosa8 0.9.36 writes one pcapng file at that path. On 0.1.0, create the sandbox with kosa8 sandbox create NAME --pcap FILE and drive it from Java by name. |
ApiException 500: no such sandbox from startSandbox | kosa8 0.9.36 answers 500, not 404, for this case. | Catch ApiException rather than NotFoundException here, or check getSandbox(name) != null first. |
Kosa8Exception: refusing to talk to … over plain http | A non-loopback http:// worker. | Use https://; or, on a link that is already private, insecure(true) / KOSA8_INSECURE=1. |
AuthException (401) from a worker, although KOSA8_TOKEN is set | KOSA8_TOKEN is used only when the host came from KOSA8_HOST. | Call token(…) when you call host(…). |
OverlappingFileLockException from checkpoint, rewind or deleteSandbox (0.1.0 only) | Two clients in one JVM, each with its own default checkpoint store, updated the file at once. Fixed in 0.1.1: stores on one path share a lock. | Upgrade to 0.1.1. On 0.1.0, share one Kosa8Client, or build each with the same CheckpointStore instance. |
CheckpointException: timed out after 10s waiting for …checkpoints.json.lock | Another process (often a CLI command, or a stuck program) held the checkpoint file lock for longer than the store's limit. | Find the holder (lsof ~/.kosa8/checkpoints.json.lock), or allow longer: builder().checkpoints(new FileCheckpointStore(path, Duration.ofSeconds(60))). |
| A checkpoint taken from the CLI is missing from Java's list, or the other way round (Linux) | Java's fcntl lock and the CLI's flock lock do not exclude each other on Linux, so two updates at the same instant can lose one record. On macOS they do exclude each other (tested). | Do not checkpoint the same machine from the CLI and Java at the same moment on Linux, or give the SDK its own store (MemoryCheckpointStore, or FileCheckpointStore on another path). |
CheckpointException: restore failed and X no longer exists … (0.1.0: "… is now stopped") | The restore inside a rewind failed; on a Mac usually a locked screen. The sandbox has been deleted. | Fix the cause and run the restoreSnapshot(…) call in the message. Details, including clean-up if you give up. |
CheckpointException: no checkpoint "X" for sandbox "Y" | No id or label matches. Labels match without regard to case; ids match exactly. | sb.checkpoints() or kosa8 checkpoint ls Y. |
Kosa8Exception: egressAllow already limits the network … | egressAllow together with egress("any") or another non-deny value. | Use one or the other. |
Kosa8Exception: exec does not take env | 0.1.1 refuses exec with Options.Run.env; the daemon's exec has no environment (0.1.0 dropped it silently). | Wrap the command: List.of("env", "K=V", "cmd"), or set the environment when starting the container with startInteractive. |
Kosa8Exception: stdin of container … was already sent and is closed | A second writeStdin to the same container from the same client. One body is the whole of stdin; the daemon closes it when the body ends (0.1.0 answered ok and the input was lost). | Send everything in one call, or pass one InputStream that yields input over time (a PipedInputStream). |
Kosa8Exception: mount "…": want host:guest or host:guest:ro | A mount string without exactly a host and a guest path, and optionally :ro/:rw. | Fix the string. (In 0.1.0, every mount failed at the daemon with 500 mount has no guest path; upgrade.) |
Kosa8Exception: mount "…": both paths must be absolute … | A relative host path (mnt:/work) or a guest path without a leading /. Checked since 0.1.2. | Path.of("mnt").toAbsolutePath() + ":/work". |
| Output callbacks see half lines, or two lines at once | Callbacks receive chunks as the daemon sends them, not lines. | Buffer and split on \n yourself. |
| stderr appears before stdout that was printed earlier | Order is kept within a stream, not across the two. | If order matters, have the command write both to one stream (2>&1). |
| Sandboxes pile up after crashes | Sandboxes outlive the JVM, and the SDK has no shutdown hook. | try/finally with delete(), plus a sweep by label. |
What changed in 0.1.1 and 0.1.2
0.1.1 fixes the problems found while these pages were written and tested. If you are on 0.1.0, these are the differences you will notice when you move to 0.1.1.
| Area (0.1.1) | 0.1.0 | 0.1.1 |
|---|---|---|
| Two clients in one JVM checkpointing | OverlappingFileLockException (unchecked, not a Kosa8Exception) | They queue on a shared in-process lock |
| Waiting for the checkpoint file lock | Forever | 10 s by default (new FileCheckpointStore(path, Duration)), then CheckpointException |
| Two checkpoints of one sandbox at once | Could pick the same id | The loser of the 409 steps to the next id |
Options.Create.mounts | Every mount refused by the daemon (500) | Works; bad strings throw before sending |
| Traffic capture | capture(true) got a 500 | capture(String path); capture(true) throws before sending |
exec with env | Variables silently dropped | Kosa8Exception |
Second writeStdin to a container | Answered ok; input never seen | Kosa8Exception |
| Failed rewind message | Said the sandbox "is now stopped" | Says it was deleted and the checkpoint is intact |
Endpoint.toString() | Printed the bearer token | token=*** |
Sandbox handle | No stdin, attach or frames | execFrames, startInteractive, writeStdin, attach |
0.1.2
| Area | 0.1.1 | 0.1.2 |
|---|---|---|
capture(String) wording | Parameter hostDir; javadoc and both errors said "host directory" | Parameter hostFile; the javadoc and errors say file, which is what the daemon writes |
| Mount paths | Relative paths sent to the daemon | Both paths must be absolute; otherwise Kosa8Exception before sending |
Unchanged, because they are the daemon's behaviour: a timeout does not stop the command; a
missing image or container is a StreamException; a missing sandbox on start or snapshot
on restore is a 500.
Java developer guide for how each feature works, and the API reference for which methods throw what. For problems with kosa8 itself rather than the SDK, see When something is wrong.