Tencent/WeKnora · error
sandbox: remove session input %s: %w
Error message
sandbox: remove session input %s: %w
What it means
RemoveSessionInputPath deletes a staged attachment from the session's live sandbox; MakeDir-style provisioning is intentionally skipped (no-op when no sandbox is bound). If a sandbox IS bound and m.client.Remove fails, the error is wrapped as "sandbox: remove session input <path>".
Source
Thrown at internal/sandbox/session_manager.go:576
// RemoveSessionInputPath deletes a staged attachment. It is a no-op when the
// session has no live sandbox and never provisions one.
func (m *SessionBoundManager) RemoveSessionInputPath(
ctx context.Context, sessionID, targetPath string,
) error {
if err := m.requireRemoteBackend(); err != nil {
return err
}
clean, err := cleanSessionInputPath(targetPath)
if err != nil {
return err
}
handle, ok, err := m.lookupSessionHandle(ctx, sessionID)
if err != nil || !ok {
return err
}
if err := m.client.Remove(ctx, handle, clean); err != nil {
return fmt.Errorf("sandbox: remove session input %s: %w", clean, err)
}
return nil
}
// ListSessionFiles walks dir under the session's live sandbox recursively.
// Returns nil (no error) when the session has no bound sandbox so callers can
// treat "no sandbox" and "empty output" uniformly.
func (m *SessionBoundManager) ListSessionFiles(
ctx context.Context, sessionID, dir string,
) ([]RemoteDirEntry, error) {
if strings.TrimSpace(dir) == "" {
return nil, errors.New("sandbox: dir required for ListSessionFiles")
}
handle, ok, err := m.lookupSessionHandle(ctx, sessionID)
if err != nil || !ok {
return nil, err
}
return m.listFilesRecursive(ctx, handle, dir)View on GitHub (pinned to 988cbb0330)
Solutions
- Check the wrapped error; treat 'not found' as success in your own retry logic if the provider errors on it.
- Verify the path matches how the file was staged (same clean path).
- Confirm the sandbox handle is current; re-resolve the session and retry.
- Retry with backoff for transient provider errors.
Example fix
// before
err := mgr.RemoveSessionInputPath(ctx, sessionID, p)
if err != nil { return err } // fails on already-deleted file
// after
if err := mgr.RemoveSessionInputPath(ctx, sessionID, p); err != nil && !isNotFound(err) {
return err
} Defensive patterns
Strategy: try-catch
Validate before calling
// only attempt removal when a live sandbox exists
if ok, _ := store.HasLiveHandle(ctx, sessionID); !ok {
return nil // no sandbox: nothing staged to remove
} Try / catch
if err := mgr.RemoveSessionInputPath(ctx, sessionID, p); err != nil {
if isNotFound(err) {
return nil // already gone: treat as success
}
return fmt.Errorf("cleanup attachment %s: %w", p, err)
} Prevention
- Track which paths were actually staged so cleanup only targets existing files.
- Treat not-found removals as idempotent success in cleanup code.
- Clean up attachments before sandbox TTL expiry while the handle is live.
- Serialize cleanup operations to avoid double-delete races.
When it happens
Trigger: Calling RemoveSessionInputPath when lookupSessionHandle returns a live handle but client.Remove fails — file already gone with strict provider, permission denied, invalid path, sandbox terminated mid-call, or provider API error.
Common situations: Double-delete races (file removed concurrently), stale paths after session restart with a fresh sandbox, provider 404 surfaced as an error, or permission issues on staged input files.
Related errors
- sandbox: ensure session dir %s: %w
- sandbox: create input directory: %w
- sandbox: create workspace directory: %w
- sandbox: docker client requires a config
- sandbox: docker backend requires an image
AI-assisted analysis of Tencent/WeKnora@988cbb0330 (2026-09-02).
Data as JSON: /api/errors/4875e90793335d76.
Report an issue: GitHub.