Bug: Strix 1.4.1 Caido bootstrap hangs on project.select(project.id) — createProject returns null to guest tokens in strix-sandbox:1.1.0
Environment
- strix-agent 1.4.1 (released 2026-07-27)
- strix-sandbox:1.1.0 (bundled in strix CLI on first run)
- caido-sdk-client 0.3.0 (resolved from
>=0.2.0; verified 0.2.0 source is identical)
- Network mode:
--network=host (because the new shared-network mode in v1.3.0 doesn't fit our VM resource model)
- Target: local directory
Symptom
Strix CLI completes login, launches the sandbox container, Caido HTTP endpoint responds on the host-mapped port (e.g. 127.0.0.1:32771), loginAsGuest GraphQL mutation succeeds with a valid access token, but project.create({ name: "sandbox", temporary: true }) then hangs the next call (project.select) until the SDK executes its 30s timeout. Wrapper exit:
caido_sdk_client.errors.graphql.OperationUserError:
Source: TimeoutError on Caido project.select GraphQL call
Direct repro
With the sandbox running and a guest token in hand (curl-able from outside the sandbox on the host port mapping), the GraphQL createProject returns a null project:
PORT=$(docker ps --format '{{.Ports}}' | grep -oE '127.0.0.1:[0-9]+->48080' | head -1 | cut -d: -f2 | cut -d- -f1)
TOKEN=$(curl -sf -X POST http://127.0.0.1:$PORT/graphql \
-H 'Content-Type: application/json' \
-d '{"query":"mutation { loginAsGuest { token { accessToken } } }"}' \
| python3 -c "import json,sys; print(json.load(sys.stdin)['data']['loginAsGuest']['token']['accessToken'])")
echo "token=$TOKEN" # works fine
curl -sf -X POST http://127.0.0.1:$PORT/graphql \
-H 'Content-Type: application/json' \
-H "Authorization: Bearer $TOKEN" \
-d '{"query":"mutation { createProject(input: { name: \"smoke\", temporary: true }) { project { id name } } }"}'
# → {"data":{"createProject":{"project":null}}}
Same payload from a non-guest (admin-created) account presumably works — I haven't been able to test because Caido's auth model is closed-source and I can't create an admin without first getting past createProject.
What I've ruled out
- SDK bug? caido-sdk-client 0.2.0 and 0.3.0 source diff for
project.create and project.select is identical (both raise MissingExpectedValueError on null payload). Updated SDK from latest pip resolves; downgrading to 0.2.0 wouldn't change behavior.
- Network/port resolution? In v1.3.0 strix added a shared-network port resolver that expects the sandbox on
STRIX_DOCKER_SANDBOX_NETWORK. With --network=host, the parent's resolver fires and gets the host port mapping correctly. Sandbox container + Caido all reachable. Confirmed loginAsGuest works on that URL.
- Resource exhaustion? Increased
--memory from 2g → 3g. No change in behavior.
My read of the cause
The Caido server shipped with strix-sandbox:1.1.0 returns null to a guest token's createProject. The closed-source Caido permission model apparently changed so guests have read-only project access but not create-project — and the strix SDK doesn't handle the null gracefully (it just calls select(project.id) on the resulting object, which then times out the GraphQL handshake).
Two reasonable fixes:
- Caido docs / source change: re-grant create-project to guest tokens, OR ship a different bootstrap path in the sandbox that sets up an admin before project creation.
- strix-side: check
createProject.project for null and either (a) retry with a different token flow, (b) use an existing project from a list query, or (c) surface a clear error instead of timing out.
Workaround in the meantime
I've parked Strix and pivoted to semgrep + trivy fs (run from outside the container; trivy is the trivy AQUA scanner, not Caido). Real-world value caught in our first scan: 15 HIGH CVEs flagged on a Next.js project, 90 seconds, no LLM tokens. So we're not blocked. But the Strix path is the more interesting one for our use case (live HTTP exploit automation, browser-based XSS/CSRF checks) and would be useful to get back to.
Repo / commit references
Bug: Strix 1.4.1 Caido bootstrap hangs on
project.select(project.id)— createProject returnsnullto guest tokens in strix-sandbox:1.1.0Environment
>=0.2.0; verified 0.2.0 source is identical)--network=host(because the new shared-network mode in v1.3.0 doesn't fit our VM resource model)Symptom
Strix CLI completes login, launches the sandbox container, Caido HTTP endpoint responds on the host-mapped port (e.g.
127.0.0.1:32771),loginAsGuestGraphQL mutation succeeds with a valid access token, butproject.create({ name: "sandbox", temporary: true })then hangs the next call (project.select) until the SDK executes its 30s timeout. Wrapper exit:Direct repro
With the sandbox running and a guest token in hand (curl-able from outside the sandbox on the host port mapping), the GraphQL
createProjectreturns anullproject:Same payload from a non-guest (admin-created) account presumably works — I haven't been able to test because Caido's auth model is closed-source and I can't create an admin without first getting past createProject.
What I've ruled out
project.createandproject.selectis identical (both raiseMissingExpectedValueErroron null payload). Updated SDK from latest pip resolves; downgrading to 0.2.0 wouldn't change behavior.STRIX_DOCKER_SANDBOX_NETWORK. With--network=host, the parent's resolver fires and gets the host port mapping correctly. Sandbox container + Caido all reachable. ConfirmedloginAsGuestworks on that URL.--memoryfrom 2g → 3g. No change in behavior.My read of the cause
The Caido server shipped with strix-sandbox:1.1.0 returns
nullto a guest token'screateProject. The closed-source Caido permission model apparently changed so guests have read-only project access but not create-project — and the strix SDK doesn't handle the null gracefully (it just callsselect(project.id)on the resulting object, which then times out the GraphQL handshake).Two reasonable fixes:
createProject.projectfor null and either (a) retry with a different token flow, (b) use an existing project from a list query, or (c) surface a clear error instead of timing out.Workaround in the meantime
I've parked Strix and pivoted to
semgrep + trivy fs(run from outside the container; trivy is the trivy AQUA scanner, not Caido). Real-world value caught in our first scan: 15 HIGH CVEs flagged on a Next.js project, 90 seconds, no LLM tokens. So we're not blocked. But the Strix path is the more interesting one for our use case (live HTTP exploit automation, browser-based XSS/CSRF checks) and would be useful to get back to.Repo / commit references