{"record":{"id":"4875e90793335d76","repo":"Tencent/WeKnora","slug":"sandbox-remove-session-input-s-w","errorCode":null,"errorMessage":"sandbox: remove session input %s: %w","messagePattern":"sandbox: remove session input (.+?): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/sandbox/session_manager.go","lineNumber":576,"sourceCode":"\n// RemoveSessionInputPath deletes a staged attachment. It is a no-op when the\n// session has no live sandbox and never provisions one.\nfunc (m *SessionBoundManager) RemoveSessionInputPath(\n\tctx context.Context, sessionID, targetPath string,\n) error {\n\tif err := m.requireRemoteBackend(); err != nil {\n\t\treturn err\n\t}\n\tclean, err := cleanSessionInputPath(targetPath)\n\tif err != nil {\n\t\treturn err\n\t}\n\thandle, ok, err := m.lookupSessionHandle(ctx, sessionID)\n\tif err != nil || !ok {\n\t\treturn err\n\t}\n\tif err := m.client.Remove(ctx, handle, clean); err != nil {\n\t\treturn fmt.Errorf(\"sandbox: remove session input %s: %w\", clean, err)\n\t}\n\treturn nil\n}\n\n// ListSessionFiles walks dir under the session's live sandbox recursively.\n// Returns nil (no error) when the session has no bound sandbox so callers can\n// treat \"no sandbox\" and \"empty output\" uniformly.\nfunc (m *SessionBoundManager) ListSessionFiles(\n\tctx context.Context, sessionID, dir string,\n) ([]RemoteDirEntry, error) {\n\tif strings.TrimSpace(dir) == \"\" {\n\t\treturn nil, errors.New(\"sandbox: dir required for ListSessionFiles\")\n\t}\n\thandle, ok, err := m.lookupSessionHandle(ctx, sessionID)\n\tif err != nil || !ok {\n\t\treturn nil, err\n\t}\n\treturn m.listFilesRecursive(ctx, handle, dir)","sourceCodeStart":558,"sourceCodeEnd":594,"githubUrl":"https://github.com/Tencent/WeKnora/blob/988cbb03305e055d8ebb7d46d9ac6cc0803cd074/internal/sandbox/session_manager.go#L558-L594","documentation":"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>\".","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nerr := mgr.RemoveSessionInputPath(ctx, sessionID, p)\nif err != nil { return err } // fails on already-deleted file\n// after\nif err := mgr.RemoveSessionInputPath(ctx, sessionID, p); err != nil && !isNotFound(err) {\n    return err\n}","handlingStrategy":"try-catch","validationCode":"// only attempt removal when a live sandbox exists\nif ok, _ := store.HasLiveHandle(ctx, sessionID); !ok {\n    return nil // no sandbox: nothing staged to remove\n}","typeGuard":null,"tryCatchPattern":"if err := mgr.RemoveSessionInputPath(ctx, sessionID, p); err != nil {\n    if isNotFound(err) {\n        return nil // already gone: treat as success\n    }\n    return fmt.Errorf(\"cleanup attachment %s: %w\", p, err)\n}","preventionTips":["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."],"tags":["go","sandbox","filesystem","delete"],"backgroundTag":"remote-file-delete-failed","analyzedSha":"988cbb03305e055d8ebb7d46d9ac6cc0803cd074","analyzedAt":"2026-09-02T14:41:08.344Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}