Skip to content

Troubleshooting

The errors you're most likely to meet, what they mean, and how to fix them.

Tatolab’s errors try to name the problem and the fix. When one isn’t clear, find it here. For a stream that runs but misbehaves, start with Inspect a running stream.

error: no runtime is running on this machine: nothing answers at …

The runtime isn’t running, so no command can reach it.

  • Mac: open Tatolab and check that Run Tatolab is on in its menu.
  • Linux: systemctl --user start tatolabd, and systemctl --user status tatolabd to see why it stopped.
  • Source build: run tatolabd in a terminal of its own.

If the message goes on to say the machine’s runtime is held by another user, that runtime serves their account, not yours. A machine runs one runtime, for one user, at a time.

another runtime holds this machine: …

A tatolabd is already running. The message gives its user, process ID and executable. Use that one, or stop it before starting another. A common cause is a tatolabd started in a terminal while the installed service is also running.

the machine runtime lock cannot be taken: /Library/Application Support/Tatolab … does not exist (macOS)

The Tatolab app creates that folder on its first launch. Open the app once. Without the app, for a source build, run the sudo commands the message prints, once.

DisplayWindow: no window — running degraded (frames drained, nothing shown)

The window couldn’t open, usually because the runtime has no display. The rest of the stream keeps running. On Linux, the runtime picks up your desktop’s display when it starts. The installed service restarts itself when you log in to a desktop; a tatolabd you started by hand needs restarting from a terminal inside the desktop session. On a machine with no desktop, leave windows out and look at frames with tatolab exchange.

No usable Vulkan driver (ICD) was found or No Vulkan loader library could be opened (Linux)

The GPU driver’s Vulkan support is missing. Install your GPU’s Vulkan driver (the proprietary NVIDIA driver, or mesa-vulkan-drivers for AMD and Intel) and the Vulkan loader (libvulkan1), then check that vulkaninfo --summary works.

no stream.py in …

tatolab run and tatolab dev look for stream.py in the current folder only, never in parent folders. Run them from the project folder, point at it with --dir, or name the file with -f.

… has no .venv/bin/python; run uv sync in …

The runtime runs your stream with the project’s own environment, in <project>/.venv. Run uv sync in the project folder. If you pointed at another folder, check --dir.

… cannot import tatolab.stream: add tatolab-stream to the project's dependencies

The project doesn’t depend on tatolab-stream. Run uv add tatolab-stream.

node … is defined in the entry file

Each Python node runs in its own process, which imports the class by its module path, and stream.py can’t be imported that way. Move the class into a module of its own, such as nodes/detector.py, and import it into stream.py. The error suggests a module name.

The same goes for a node class defined inside a function (… is defined inside a function): move it to the top level of a module. If the function’s arguments shaped the class, pass them as the node’s settings instead.

tatolab dev: no stream is loaded — fix it and save again

The stream failed to load, and no earlier version was running to fall back on. The error is printed just above. Fix it and save.

no stream.py in …, only an app.py

The current convention is stream.py with a @stream function. Older projects and the repository’s examples use app.py with setup(rt), which is being replaced. To run a @stream function from another file, name it with -f. See Examples for the examples’ streams written the current way.

a stream named … is already loaded in this runtime, from …

Stream names are unique on a machine, and the message names the project using this one. Stop or remove that stream, or load yours under another name with --name.

the stream name … is held by a kept stream from … (or by a stopped or failed one)

A kept stream holds its name even while it’s stopped or failed, which is what you meet when you run tatolab dev in a project whose stream you kept. Remove the kept one while you edit (tatolab rm <name>, then tatolab run -d again when you’re done), or load yours with --name.

input port 'video' must declare a delivery_profile

Every @node.input needs delivery_profile="newest" or "ordered". See delivery profiles.

… declares the port name 'video' more than once

Inputs and outputs share one set of names on a node. Rename one, such as video in and processed_video out.

… declares no input ports, so it must declare an execution mode

A source has nothing to react to. Use @node(execution="continuous", interval_ms=...) to run on a timer, or execution="manual" to drive it yourself.

A node fails to start with unexpected keyword argument or unknown field

A misspelled key in the config you passed to stream_builder.add, or a key the node doesn’t have. The message names it. Built-in nodes and dataclass settings refuse unknown keys this way; pydantic models ignore them unless you set extra="forbid", and TypedDict settings take anything, so a typo there goes unnoticed. For a TypedDict, build the dict by calling it, as in config=DetectorConfig(threshold=0.5), and your type checker catches the typo.

node `…` has no input port `…`

The stream connects to a port the node doesn’t have. The message lists the ports it does have. Check the spelling, and check that no output method has the same name as an input method: Python keeps only the last method of a name, so the input disappears.

A GLSL error

The message gives the line number within your effect string. Check for a missing semicolon, and that effect returns a vec4.

No camera, or the wrong one

CameraSource uses the first camera it finds unless device_id names one: a path like /dev/video2 on Linux (list them with v4l2-ctl --list-devices), or a camera’s unique ID on macOS. A named camera that can’t be opened is refused by name. With no camera at all, use TestPatternSource (tatolab new … --test-pattern).

No picture on macOS

The first run asks for camera access without blocking the stream: frames start once you allow it. If you refused, allow it in System Settings → Privacy & Security → Camera. The prompt and the setting name the app that started the runtime: Tatolab, or your terminal app for a source build.

No sound, or a recording that stays empty

Check the microphone permission on macOS, and the device name if you set device_id. An Mp4Sink waits until every track has sent its first data before it writes anything. Until then it logs waiting to write moov once a second, with the tracks it’s still waiting for, which is how a track that never starts shows up.

A VirtualCameraSink can’t create its camera

Run tatolab enable-virtual-camera once. It needs the v4l2loopback module for your kernel (v4l2loopback-dkms on Debian and Ubuntu). Until then, the sink presents a PipeWire camera instead. See Virtual camera.

the encoder session could not be minted; every later frame is discarded

The GPU or driver has no hardware video encoder Tatolab can use for that codec. Try the other codec (H265Encoder instead of H264Encoder, or the reverse), and check your driver’s Vulkan Video support on Linux.

A USB webcam runs at a few frames per second on Linux

CameraSource reads uncompressed video only, and picks the largest size within max_width and max_height. Most USB 2.0 webcams send uncompressed HD at 5 to 10 frames per second; their faster HD modes are MJPEG, which isn’t read yet. Lower the limits ("max_width": 640, "max_height": 480 usually runs at 30), or use a USB 3 camera. v4l2-ctl --list-formats-ext lists what your camera offers.

no tappable channel named …

tatolab tap, tatolab exchange --channel and an agent’s tap can only sample an output that something reads: a link in its own stream, or another stream reading it. Connect something to the output, or sample one that already has a reader. Exposure doesn’t matter here.

bash: tatolab: command not found over ssh

A command run over ssh gets a non-interactive shell, and on Debian and Ubuntu that shell doesn’t have ~/.local/bin on its PATH. Give the path instead: ssh door-box .local/bin/tatolab streams.

tatolab logs --list shows nothing

Each stream’s log files live in its project’s .streamlib/ folder, so run tatolab logs --list in the project folder. For a running stream, tatolab logs --stream <name> works from anywhere.

Open an issue on GitHub with the command you ran, the full error, and tatolab --version, or email hello@tatolab.com.