Skip to content

fix: recognize confirmed container loss when resuming Daytona leases - #13792

Merged
devinfoley merged 2 commits into
masterfrom
fix/daytona-missing-container-resume
Sep 22, 2026
Merged

devinfoley merged 2 commits into
masterfrom
fix/daytona-missing-container-resume

Conversation

@devinfoley

@devinfoley devinfoley commented Sep 22, 2026

Copy link
Copy Markdown
Contributor

Thinking Path

  • Paperclip is the open source app people use to manage AI agents for work.
  • Reusable sandbox leases preserve a task's execution state between runs.
  • Daytona can keep a sandbox API record after its underlying container is gone.
  • The resume path sees an existing record and rejects its unrecoverable error forever.
  • The host already has a replacement path that verifies native-runner backups.
  • This pull request recognizes only a freshly confirmed missing-container response and uses that existing path.
  • Unknown failures retain the exact lease for later investigation.

Linked Issues or Issue Description

What happened?

Daytona returns HTTP 200 for a retained sandbox, with state error, recoverable: false, and an explicit error that its own container no longer exists. Paperclip rejects resume before reaching its existing missing-sandbox handling. Repeated resume attempts cannot use an available verified backup.

Expected behavior

Treat a freshly confirmed missing container like a missing sandbox. Let the host apply its existing replacement policy and native-runner backup verification. Preserve the lease for unknown or uncertain failures.

Steps to reproduce

  1. Resume a recorded Daytona lease whose API record remains after the container is lost.
  2. Have the provider return not found: failed to inspect sandbox container <id>: Error response from daemon: No such container: <id> for that same sandbox, with state error and recoverable: false.
  3. Observe the unrecoverable resume error, even when the host can verify the retained native-runner backup.

Paperclip version or commit

ded156a.

Deployment mode

Self-hosted server with the Daytona provider.

What Changed

  • Require the exact missing-container response, matching sandbox and container identities, and an explicit unrecoverable error state.
  • Refresh provider state within the configured liveness timeout before returning an expired lease. A typed not-found response also confirms loss.
  • Evict the stale handle. Leave replacement and backup validation with the existing host lifecycle.
  • Preserve recoverable errors, unknown errors, failed confirmation reads, and mismatched refreshed identities.
  • Add 15 provider regressions and document the lifecycle behavior.

Verification

  • Daytona plugin suites: 251 tests pass; 9 opt-in tests skip. New missing-container regressions failed before the change.
  • Host environment-runtime suite: 93 tests pass, including refusal to destroy or allocate replacement state without a verified native-runner backup.
  • Standalone Daytona tsc --noEmit and pnpm build pass.
  • Read-only provider inspection confirmed the exact response and matching sandbox/container identities. The existing on-stack native-runner backup verifier passed for that retained lease. No sandbox was restarted, replaced, or deleted, and no task was retried.
  • The plugin is excluded from the root workspace and was tested and built separately. The most recent full-root checks in this session had 8,211 passing tests and 14 existing macOS embedded-PostgreSQL/runtime-cache failures; root typecheck/build were blocked by missing cargo. Linux CI must pass before merge.

Risks

Replacement can lose state if loss is misclassified. Recognition is intentionally narrow and requires a fresh provider confirmation for the same sandbox. The native-runner backup gate remains unchanged. Other errors still preserve the lease. The plugin does not delete or create a sandbox in this branch; the host owns those actions. No schema, credential, dependency-version, or retry-policy changes.

Model Used

OpenAI GPT-6 via Codex, with reasoning, shell tools, code editing, and read-only provider inspection. The exact model snapshot and context-window size are not exposed by this session.

Checklist

  • I have included a thinking path that traces from project context to this change
  • I have specified the model used (with version and capability details)
  • I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work
  • I have searched GitHub for duplicate or related PRs and linked them above
  • I have either (a) linked existing issues with Fixes: # / Closes # / Refs # OR (b) described the issue in-PR following the relevant issue template
  • I have not referenced internal/instance-local Paperclip issues or links (only public GitHub #NNN / github.com/paperclipai/paperclip URLs)
  • My branch name describes the change (e.g. docs/..., fix/...) and contains no internal Paperclip ticket id or instance-derived details
  • I have run tests locally and they pass (plugin and host lifecycle suites; full-root limitations described above)
  • I have added or updated tests where applicable
  • I have updated relevant documentation to reflect my changes
  • I have considered and documented any risks above
  • All Paperclip CI gates are green
  • Greptile is 5/5 with no open P2s, recommendations, or follow-ups
  • I will address all Greptile and reviewer comments before requesting merge

Daytona can retain a sandbox API record after its container disappears.
Confirm the exact missing-container response with a bounded fresh read,
then let the host apply its existing replacement and backup policy.
Preserve unknown failures, recoverable errors, and identity mismatches.

Verified 249 provider tests, 93 host lifecycle tests, plugin typecheck and
build. Added 13 regressions. Read-only inspection confirmed the provider
response and an existing verified backup without changing live state.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
@greptile-apps

greptile-apps Bot commented Sep 22, 2026

Copy link
Copy Markdown
Contributor

RetriggerConfidence Score: 5/5

The PR appears safe to merge, with the previously reported opaque-ID limitation fixed and no new actionable issue identified.

Summary

This PR updates Daytona lease resumption to recognize a retained sandbox record whose underlying container is freshly confirmed missing.

  • Requires the exact missing-container response for the sandbox’s opaque identifier and an explicitly unrecoverable error state.
  • Refreshes provider state within the configured liveness timeout before expiring the lease.
  • Preserves the lease on unknown errors, failed confirmation, or identity mismatch.
  • Adds regression coverage and documents the host’s backup-gated replacement behavior.

Reviews (2) · Last reviewed commit: "Match opaque Daytona sandbox IDs literal..."

Comment thread packages/plugins/sandbox-providers/daytona/src/plugin.ts Outdated
Compare the known provider message against the exact sandbox ID instead
of requiring UUID syntax. Cover opaque IDs and regex punctuation while
retaining fresh confirmation and the existing backup guard.

Verified all 251 provider tests, plugin typecheck, and build.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
@devinfoley
devinfoley merged commit 1f3ff75 into master Sep 22, 2026
55 checks passed
@devinfoley
devinfoley deleted the fix/daytona-missing-container-resume branch September 22, 2026 03:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant