Install
$ agentstack add skill-impertio-studio-speckle-claude-skill-package-speckle-errors-transport ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
speckle-errors-transport
Diagnostic Decision Tree
Transport operation failed
|
+-- Network/HTTP error?
| +-- 401 / 403 → AUTH EXPIRY (Section 1)
| +-- 404 → WRONG STREAM ID (Section 2)
| +-- 408 / timeout → TIMEOUT (Section 3)
| +-- 502 / 503 / 504 → SERVER UNAVAILABLE (Section 4)
| +-- ConnectionError / SSLError → NETWORK (Section 5)
|
+-- SQLite error?
| +-- "database is locked" → SQLITE LOCK (Section 6)
| +-- "disk I/O error" → DISK FULL (Section 7)
| +-- "unable to open database" → PATH / PERMISSION (Section 8)
|
+-- Memory error?
| +-- MemoryError / OutOfMemoryException → MEMORY LIMIT (Section 9)
|
+-- SpeckleException?
| +-- "No transport" → NO TRANSPORT CONFIG (Section 10)
| +-- "get_object not implemented" → WRONG METHOD (Section 11)
|
+-- Multi-transport failure? → PARTIAL FAILURE (Section 12)
+-- OperationCanceledException → CANCELLATION (Section 13)
+-- Progress callback throws → PROGRESS ERROR (Section 14)
Section 1: Authentication Expiry During Transfer
Symptom: HTTP 401/403 partway through a send/receive. Operation starts but fails after minutes.
Cause: Speckle tokens expire. ServerTransport stores the token at construction and reuses it for ALL requests. Long transfers can outlive the token.
Fix: ALWAYS create a fresh ServerTransport immediately before each operation. NEVER reuse across delays of more than 30 minutes.
# Create transport JUST before use
transport = ServerTransport(stream_id="abc123", client=client)
root_id = operations.send(base=my_object, transports=[transport])
// Set generous timeout for large models
var transport = new ServerTransport(account, "streamId", timeoutSeconds: 300);
Section 2: Wrong Stream ID (404)
Symptom: HTTP 404 on upload/download. Auth succeeds but operations fail.
Cause: The stream_id does not exist on the target server. Common when mixing IDs from different servers or after stream deletion.
Fix: ALWAYS verify stream existence before creating transport.
stream = client.stream.get(stream_id="abc123") # Raises if not found
transport = ServerTransport(stream_id="abc123", client=client)
Rule: NEVER mix stream IDs from one server with credentials for another.
Section 3: Timeout Errors
Symptom: TimeoutError, requests.exceptions.Timeout, or TaskCanceledException. Common with models >100MB.
Cause: HTTP request exceeded configured timeout. C# default is 60 seconds per request.
Fix:
- C#: Set
timeoutSeconds: 300(or higher) at transport construction - Python: Configure at session level or use client-based auth
Rule: ALWAYS set timeoutSeconds to at least 300 for models larger than 50MB. NEVER use the default 60-second timeout for production workloads.
Section 4: Server Unavailable (502/503/504)
Symptom: Intermittent HTTP 502/503/504 during batch uploads.
Cause: Speckle Server or reverse proxy is overloaded, restarting, or down.
Fix: Implement retry with exponential backoff. ALWAYS create a fresh ServerTransport per retry. NEVER retry immediately — wait at least 5 seconds.
for attempt in range(3):
try:
transport = ServerTransport(stream_id=sid, client=client)
return operations.send(base=obj, transports=[transport])
except Exception:
if attempt == 2: raise
time.sleep(2 ** attempt * 5) # 5s, 10s, 20s
Section 5: Network Connection Errors
Symptom: ConnectionError, SSLError, ConnectionRefusedError, HttpRequestException.
Cause: No connectivity, DNS failure, SSL cert issues (self-hosted), firewall blocking port 443, or missing proxy config.
Fix: Verify connectivity before long operations. Configure proxy via HTTPS_PROXY environment variable. NEVER ignore SSL errors in production.
Section 6: SQLite Database Lock
Symptom: sqlite3.OperationalError: database is locked or SqliteException: SQLite Error 5.
Cause: SQLite uses file-level locking. Multiple processes writing to the same Data.db simultaneously causes lock errors. The default cache is shared across ALL connectors.
Fix: Use separate scope names for concurrent operations:
transport_a = SQLiteTransport(scope="ProjectA") # Creates ProjectA.db
transport_b = SQLiteTransport(scope="ProjectB") # Creates ProjectB.db
Rules:
- NEVER share the same scope across concurrent processes
- NEVER open Speckle SQLite with an external tool while connectors are running
- ALWAYS call
close()(Python) orDispose()(C#) when done
Section 7: Disk Full / I/O Errors
Symptom: sqlite3.OperationalError: disk I/O error or SQLite Error 13: database or disk is full.
Cause: The SQLite cache grows monotonically — Speckle NEVER purges cached objects. Heavy users accumulate 10GB+ caches.
Fix: Delete the cache file when no connectors are running (safe — recreated automatically). Use use_default_cache=False in serverless environments.
Rules:
- NEVER delete the cache while Speckle connectors are running
- ALWAYS monitor disk space on production machines
Section 8: SQLite Path / Permission Errors
Symptom: unable to open database file at transport construction.
Cause: Base path does not exist, no write permissions, or invalid characters. On Linux, $XDG_DATA_HOME may point to non-existent directory.
Fix: Specify a writable path explicitly:
import os
os.makedirs("/tmp/speckle-cache", exist_ok=True)
transport = SQLiteTransport(base_path="/tmp/speckle-cache", scope="MyProject")
Rule: NEVER assume %APPDATA% or ~/.config is writable in CI/CD — specify a custom base_path.
Section 9: Memory Exhaustion
Symptom: MemoryError or OutOfMemoryException during serialization or get_all_objects().
Cause:
- Calling
get_all_objects()on a large cache (loads everything into memory) - Serializing very deep/wide trees without detachment
- Using
MemoryTransportfor large datasets
Rules:
- NEVER call
get_all_objects()on databases larger than 100MB - NEVER use
MemoryTransportfor datasets exceeding available RAM - ALWAYS use
@detach_propertyfor large child collections - ALWAYS set
use_default_cache=Trueduring send to enable streaming serialization
Section 10: No Transport Configured
Symptom: SpeckleException: Provide at least one transport...
Cause: send() called with transports=None AND use_default_cache=False.
Fix: ALWAYS provide at least one transport, OR leave use_default_cache=True (the default).
Section 11: Wrong Transport Method Call
Symptom: SpeckleException from server_transport.get_object(id) in Python.
Cause: Python ServerTransport.get_object() is NOT implemented — ALWAYS raises. Use operations.receive() or copy_object_and_children() instead.
# WRONG: server_transport.get_object(obj_id) # RAISES
# CORRECT:
obj = operations.receive(obj_id, remote_transport=server_transport)
Rule: NEVER call get_object() directly on a Python ServerTransport. ALWAYS read from a local transport after copying.
Section 12: Multi-Transport Partial Failure
Symptom: Send completes but data is missing from one transport.
Cause: A failure in one transport does NOT abort the others. In Python, an exception propagates and may leave other transports incomplete.
Fix: Send to each transport independently for critical workflows:
for transport in transports:
try:
operations.send(base=obj, transports=[transport])
except Exception as e:
logger.error(f"Failed on {transport.name}: {e}")
Rule: NEVER assume all transports succeeded without verification.
Section 13: Cancellation Errors
Symptom: OperationCanceledException (C#) mid-transfer.
Cause: User or code cancelled via CancellationToken. Partial data may remain in transports.
Fix: ALWAYS pass a CancellationToken in C# interactive apps. NEVER attempt rollback — partial content-addressed data is harmless.
var cts = new CancellationTokenSource();
cts.CancelAfter(TimeSpan.FromMinutes(30));
await Operations.Send(data, new[] { transport }, cancellationToken: cts.Token);
Section 14: Progress Reporting Errors
Symptom: Exception from progress callback, not from the transport. Cross-thread UI errors in C#.
Cause: IProgress callback invoked from a background thread. Updating UI without marshalling throws.
Fix: ALWAYS use new Progress(callback) which captures SynchronizationContext. NEVER implement IProgress manually without thread marshalling.
Retry Strategy Summary
| Error Type | Retry? | Max | Backoff | |-----------|--------|-----|---------| | Auth expiry (401/403) | Yes | 1 | Re-auth, new transport | | Wrong stream (404) | No | — | Fix stream ID | | Timeout (408) | Yes | 3 | Exponential | | Server down (5xx) | Yes | 3 | Exponential (5s base) | | Network error | Yes | 3 | Exponential (2s base) | | SQLite lock | Yes | 5 | Linear (0.5s increments) | | Disk full | No | — | Free space | | Path/permission | No | — | Fix config | | Memory exhaustion | No | — | Reduce payload | | No transport | No | — | Fix config | | Wrong method | No | — | Use correct API | | Multi-transport | Yes | 2 | Retry failed only | | Cancellation | No | — | User-initiated | | Progress callback | No | — | Fix callback |
Default Cache Paths
| OS | Path | |----|------| | Windows | %APPDATA%\Speckle\Data.db | | macOS | ~/.config/Speckle/Data.db | | Linux | $XDG_DATA_HOME/Speckle/Data.db or ~/.local/share/Speckle/Data.db |
Critical Rules Summary
- NEVER reuse
ServerTransportacross operations separated by >30 minutes - NEVER call
get_object()on PythonServerTransport - NEVER call
get_all_objects()on large databases - NEVER share SQLite scope across concurrent processes
- NEVER delete cache while connectors are running
- ALWAYS create fresh
ServerTransportper operation - ALWAYS use separate
scopenames for concurrent SQLite access - ALWAYS pass
CancellationTokenin C# interactive applications - ALWAYS implement retry with exponential backoff for server errors
- ALWAYS close/dispose transports when done
Reference Links
- [references/methods.md](references/methods.md) — Transport API signatures and exception types
- [references/examples.md](references/examples.md) — Working error handling code examples
- [references/anti-patterns.md](references/anti-patterns.md) — What NOT to do with transports
Official Sources
- https://speckle.guide/dev/transports.html
- https://speckle.guide/dev/python.html
- https://speckle.guide/dev/dotnet.html
- https://github.com/specklesystems/specklepy
- https://github.com/specklesystems/speckle-sharp-sdk
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: Impertio-Studio
- Source: Impertio-Studio/Speckle-Claude-Skill-Package
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.