fix: persist Daytona authentication failures - #519
Conversation
🦋 Changeset detectedLatest commit: d24d771 The changes in this PR will be included in the next version bump. This PR includes changesets to release 2 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
290e8b8 to
a1379ae
Compare
|
Rebased onto the latest |
a1379ae to
f056581
Compare
|
Rebased onto current Post-rebase validation:
The SQLite sandbox-provider contract could not execute on this host because the |
|
Rebased onto current The upstream manifest model now includes a non-Daytona stored variant. I preserved that boundary by capturing the already-narrowed Daytona manifest before the async error callback, then using that snapshot for the conditional status update; the store-level expected-manifest comparison accepts the persisted union. This keeps the stale-write guard without treating a non-Daytona record as a Daytona configuration. Validated after the rebase:
The existing SQLite/Postgres contract is unchanged by the rebase; the latter remains an environment-dependent integration boundary noted earlier. |
f056581 to
abb256d
Compare
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Want higher recall? High effort reviews run extra passes and find more bugs. A team admin can switch effort levels in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit abb256d. Configure here.
|
Follow-up on the latest store-input review: addressed in Revalidated on the current head:
This does not change the concurrency behavior; it makes omission of the conditional-write guard a type-level error. |
1ce678d to
e6ac0ed
Compare
|
Rebased onto current The stale-write findings are covered by the manifest compare-and-set path: runtime and snapshot callbacks pass the manifest used to create the client; Validated locally:
I also attempted |
29f28b5 to
7297779
Compare
|
Rebased onto current Validation after the rebase:
I also attempted the SQLite contract test that covers the stale-manifest guard. This runner cannot load its |
7297779 to
d24d771
Compare
|
Rebased the PR onto current Revalidated the changed failure-propagation paths: I did not run the Postgres/SQLite contract suite locally because it requires those backing services; the patch still includes its contract coverage and CI remains the integration check. |
|
Addressed in d24d771: |

Summary
Persist Daytona 401/403 failures as a failed sandbox-provider status instead of returning an internal settings error or losing the typed error when sandbox execution converts it to a failed result.
Closes #516
Changes
status_reasonvaluestrueforgeandtrueforge-coreHow was this tested?
pnpm --filter @truefoundry/trueforge-core test -- --runInBand tests/core/sandbox/daytonaSnapshotRegistration.test.tspnpm --filter @truefoundry/trueforge test -- --runInBand tests/unit/sandbox/providerUtils.test.tspnpm --filter @truefoundry/trueforge test:store:sqlite -- --runInBand tests/db/sqlite/sandbox-provider-store/contract.test.tspnpm --filter @truefoundry/trueforge-core typecheckpnpm --filter @truefoundry/trueforge typecheckpnpm exec eslint packages/trueforge-core/src/core/sandbox/provider/DaytonaProvider.ts packages/trueforge/src/runtime/sessionResources.ts packages/trueforge/src/sandbox/providerUtils.tsgit diff --checkValidation is intentionally scoped to the two changed packages and the Daytona failure paths; full workspace build/test and live Daytona credential revocation were not run locally. The callback is optional and database write failures are logged without replacing the original provider result. The SQLite store contract was run locally; the equivalent Postgres contract was not run because no local Postgres service was started.
Checklist
pnpm build,pnpm test,pnpm typecheck,pnpm lint:ci, andpnpm format:checkpass locallypackages/trueforge-sdk,.github/fern/openapi/openapi.json,docs/openapi.json) — fork PRs omit SDK regen; maintainers regenerate after merge.env.exampleupdated if configuration or behavior changed (not applicable: no configuration or documented API change)Note
Medium Risk
Changes tenant sandbox-provider persistence and runtime error handling on credential failures; optimistic manifest checks could leave status stale if misused, but scope is limited to Daytona auth paths.
Overview
When Daytona returns 401/403 (including wrapped
Error.causechains), the sandbox provider row is updated tofailedwith stablestatus_reasontext instead of surfacing opaque internal settings errors or losing the signal whenexecturns errors into{ success: false }.DaytonaSandboxProvidergains an optionalonErrorhook invoked fromcreateSandbox(before rethrow) andexec(before returning a failed result). Session resolution wires that hook torecordDaytonaAccessFailure, and snapshot refresh (checkSnapshotStatus) uses the same path on build/status errors.updateSandboxStatusnow accepts optionalexpected_manifestso status writes are skipped if credentials/manifest changed concurrently (Postgres + SQLite). Successful refresh updates also pass the current manifest for the same reason.Reviewed by Cursor Bugbot for commit d24d771. Bugbot is set up for automated code reviews on this repo. Configure here.