clockworklabs/SpacetimeDB · error · RangeError
Tried to read byte(s) at relative offset , but only byte(s)…
Error message
Tried to read ${n} byte(s) at relative offset ${this.offset}, but only ${this.remaining} byte(s) remain What it means
spacetime update list reads the CLI bin dir's current symlink to mark the active version. If the symlink target's final path component cannot be extracted (Path::file_name() returns None — e.g. the target is '..', '/', or ends in '..' — or is non-UTF8), the listing aborts with this error. It signals a malformed current symlink, typically left by an old or interrupted install (the surrounding comment is about migrating legacy symlink layouts).
Solutions
- Inspect the symlink: ls -l <bin-dir>/current — a healthy target looks like <bin-dir>/<x.y.z>.
- Repoint it by switching versions: spacetime update install <installed-version> --use (rewrites current via set_current_version).
- If no version is installed, delete the broken current symlink and install fresh, then use --use.
- If it regresses again after upgrading twice, report it — the updater is supposed to fix legacy symlinks after two upgrades.
Example fix
# before $ ls -l ~/.spacetime/bin/current current -> .. # malformed; `spacetime update list` fails # after $ rm ~/.spacetime/bin/current $ spacetime update install 1.7.1 --use $ spacetime update list # works, marks 1.7.1 current
Defensive patterns
Strategy: validation
Validate before calling
# BIN_DIR = the CLI bin dir (contains per-version dirs and `current`) target="$(readlink "$BIN_DIR/current" 2>/dev/null)" case "$(basename "$target")" in ''|'..') echo "current symlink malformed: $target";; esac
Prevention
- After every install/--use, run `spacetime update list` once to confirm the current marker resolves.
- Never hand-edit the current symlink; let `install --use` write it.
- Upgrade twice in a row after adopting a new release so legacy symlink fixups run (see list.rs comment).
When it happens
Trigger: The <bin-dir>/current symlink points to '..', '/', or another path whose last component is not a version directory name, so current_version() returns Some(path) whose file_name() is None or invalid.
Common situations: Interrupted install/--use leaving a half-written symlink; manual edits to the install dir; leftovers from pre-#2680 layouts that have not yet been fixed by two successive upgrades (see the comment in list.rs).
Related errors
- Cannot extract table name from query
- Cannot semijoin a table to itself
- Failed to get file_type for template file
- Cannot create new SpacetimeDB project in non-empty directory
- Cannot extract accessor name from query
AI-assisted analysis of clockworklabs/SpacetimeDB@6dee26c6ef (2026-08-20).
Data as JSON: /api/errors/037e4c7d84664850.
Report an issue: GitHub.
Appendix: source
Thrown at crates/bindings-typescript/src/lib/binary_reader.ts:43
this.offset = 0;
}
reset(input: Uint8Array | DataView) {
this.view =
input instanceof DataView
? input
: new DataView(input.buffer, input.byteOffset, input.byteLength);
this.offset = 0;
}
get remaining(): number {
return this.view.byteLength - this.offset;
}
/** Ensure we have at least `n` bytes left to read */
#ensure(n: number): void {
if (this.offset + n > this.view.byteLength) {
throw new RangeError(
`Tried to read ${n} byte(s) at relative offset ${this.offset}, but only ${this.remaining} byte(s) remain`
);
}
}
readUInt8Array(): Uint8Array {
const length = this.readU32();
this.#ensure(length);
// Return an owned copy, not a view over the reader's buffer. Decoded column
// values are handed to user code and may be retained, but the runtime reuses
// this buffer across table scans, so a view would be silently invalidated by
// the next iter()/filter(). Callers that only consume the bytes transiently
// (e.g. readString) can use readBytes directly to avoid this copy.
// https://github.com/clockworklabs/SpacetimeDB/issues/5490
return this.readBytes(length).slice();
}
readBool(): boolean {View on GitHub (pinned to 6dee26c6ef)