{"record":{"id":"c6cacdb7d9e082e7","repo":"Tencent/WeKnora","slug":"sandbox-no-live-sandbox-for-session-s","errorCode":null,"errorMessage":"sandbox: no live sandbox for session %s","messagePattern":"sandbox: no live sandbox for session (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/sandbox/session_manager.go","lineNumber":612,"sourceCode":"\treturn m.listFilesRecursive(ctx, handle, dir)\n}\n\n// StatSessionFile returns metadata for a single file without downloading\n// contents. Returns an error when no sandbox is bound: callers of this\n// method already hold a path from a prior ListSessionFiles call and should\n// not race with reaper/destroy.\nfunc (m *SessionBoundManager) StatSessionFile(\n\tctx context.Context, sessionID, filePath string,\n) (*RemoteStatEntry, error) {\n\tif strings.TrimSpace(filePath) == \"\" {\n\t\treturn nil, errors.New(\"sandbox: path required for StatSessionFile\")\n\t}\n\thandle, ok, err := m.lookupSessionHandle(ctx, sessionID)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif !ok {\n\t\treturn nil, fmt.Errorf(\"sandbox: no live sandbox for session %s\", sessionID)\n\t}\n\treturn m.client.Stat(ctx, handle, filePath)\n}\n\n// ReadSessionFile downloads a file from the session's live sandbox. Errors\n// when no sandbox is bound for the same reason as StatSessionFile.\nfunc (m *SessionBoundManager) ReadSessionFile(\n\tctx context.Context, sessionID, filePath string,\n) ([]byte, error) {\n\tif strings.TrimSpace(filePath) == \"\" {\n\t\treturn nil, errors.New(\"sandbox: path required for ReadSessionFile\")\n\t}\n\thandle, ok, err := m.lookupSessionHandle(ctx, sessionID)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif !ok {\n\t\treturn nil, fmt.Errorf(\"sandbox: no live sandbox for session %s\", sessionID)","sourceCodeStart":594,"sourceCodeEnd":630,"githubUrl":"https://github.com/Tencent/WeKnora/blob/988cbb03305e055d8ebb7d46d9ac6cc0803cd074/internal/sandbox/session_manager.go#L594-L630","documentation":"StatSessionFile stats a file in the session's live sandbox, but unlike the write paths it refuses to provision: if lookupSessionHandle reports no bound sandbox (ok == false), it returns the sentinel \"sandbox: no live sandbox for session <id>\". This means the session exists but currently has no running/registered remote sandbox.","triggerScenarios":"Calling StatSessionFile for a session whose sandbox was never provisioned, already expired/reclaimed, or whose binding was cleaned up by the session lifecycle.","commonSituations":"Statting a file after sandbox TTL expiry, checking a session that never had a file staged, calling after idle cleanup, or using a stale session ID post-restart.","solutions":["Treat this as 'no file' if a missing sandbox means no staged files, and return a not-found result to the caller.","Provision the sandbox first via a write path (e.g. WriteSessionInputFile) or resolveSession before statting.","Check whether the session's sandbox TTL expired and re-provision.","Verify the session ID is correct and still active in the binding store."],"exampleFix":"// before\nfi, err := mgr.StatSessionFile(ctx, sessionID, p)\n// after\nfi, err := mgr.StatSessionFile(ctx, sessionID, p)\nif err != nil && strings.Contains(err.Error(), \"no live sandbox for session\") {\n    return nil, os.ErrNotExist // no sandbox == no file\n}","handlingStrategy":"type-guard","validationCode":"// detect the no-live-sandbox sentinel before interpreting as a hard failure\nfunc isNoLiveSandbox(err error) bool {\n    return err != nil && strings.Contains(err.Error(), \"no live sandbox for session\")\n}","typeGuard":"func isNoLiveSandboxErr(err error) bool {\n    return err != nil && strings.Contains(err.Error(), \"no live sandbox for session\")\n}\n\n// usage\nfi, err := mgr.StatSessionFile(ctx, sessionID, p)\nswitch {\ncase isNoLiveSandboxErr(err):\n    return nil, os.ErrNotExist // no sandbox == file cannot exist\ncase err != nil:\n    return nil, err\n}","tryCatchPattern":"fi, err := mgr.StatSessionFile(ctx, sessionID, p)\nif err != nil {\n    if isNoLiveSandboxErr(err) {\n        return nil, os.ErrNotExist\n    }\n    return nil, fmt.Errorf(\"stat %s: %w\", p, err)\n}","preventionTips":["Build an isNoLiveSandbox(err) helper and use it wherever Stat/Read touch session files.","Remember Stat/Read never provision — trigger provisioning via a write path first if needed.","Track sandbox TTLs and refresh long-lived sessions proactively.","Validate session IDs against the binding store before file operations."],"tags":["go","sandbox","session","lifecycle"],"backgroundTag":"no-live-sandbox-for-session","analyzedSha":"988cbb03305e055d8ebb7d46d9ac6cc0803cd074","analyzedAt":"2026-09-02T14:41:08.344Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}