{"record":{"id":"da7029cfc4212af2","repo":"Tencent/WeKnora","slug":"sandbox-write-session-file-s-w","errorCode":null,"errorMessage":"sandbox: write session file %s: %w","messagePattern":"sandbox: write session file (.+?): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/sandbox/session_manager.go","lineNumber":554,"sourceCode":"\t\treturn err\n\t}\n\tif strings.TrimSpace(sessionID) == \"\" {\n\t\treturn errors.New(\"sandbox: session ID required for workspace write\")\n\t}\n\tclean, err := cleanSessionWorkspaceWritePath(filePath)\n\tif err != nil {\n\t\treturn err\n\t}\n\thandle, err := m.resolveSession(ctx, sessionID)\n\tif err != nil {\n\t\treturn err\n\t}\n\tm.ensureSessionWorkspaceDirs(ctx, handle, SessionOutputRoot)\n\tif err := ignoreExistingDir(m.client.MakeDir(ctx, handle, path.Dir(clean))); err != nil {\n\t\treturn fmt.Errorf(\"sandbox: create workspace directory: %w\", err)\n\t}\n\tif err := m.client.WriteFile(ctx, handle, clean, content); err != nil {\n\t\treturn fmt.Errorf(\"sandbox: write session file %s: %w\", clean, err)\n\t}\n\treturn nil\n}\n\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 {","sourceCodeStart":536,"sourceCodeEnd":572,"githubUrl":"https://github.com/Tencent/WeKnora/blob/988cbb03305e055d8ebb7d46d9ac6cc0803cd074/internal/sandbox/session_manager.go#L536-L572","documentation":"After the workspace parent directory is created, WriteSessionWorkspaceFile uploads the content via m.client.WriteFile, wrapped as \"sandbox: write session file <path>\". This is the remote write of a model-authored file failing after directory provisioning succeeded.","triggerScenarios":"Calling WriteSessionWorkspaceFile when client.WriteFile fails — network interruption, sandbox terminated during transfer, provider API rejection, size limits, or unwritable path.","commonSituations":"Large model outputs timing out, sandbox expiring mid-write, provider throttling (429), or the image making the workspace read-only.","solutions":["Read the wrapped provider error (timeout, 429, 5xx).","Retry; re-resolve the session to provision a fresh sandbox if it expired.","Increase HTTP timeout or chunk large writes.","Verify workspace permissions in the sandbox image."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// check content size and sandbox liveness before write\nif len(content) > maxWorkspaceFileBytes {\n    return fmt.Errorf(\"workspace file too large: %d bytes\", len(content))\n}\nif _, err := mgr.StatSessionFile(ctx, sessionID, \"/workspace\"); err != nil {\n    return fmt.Errorf(\"sandbox not ready: %w\", err)\n}","typeGuard":null,"tryCatchPattern":"err := mgr.WriteSessionWorkspaceFile(ctx, sessionID, p, data)\nif err != nil && strings.Contains(err.Error(), \"write session file\") {\n    // sandbox may have expired mid-write: re-resolve (provisions) and retry\n    if retryErr := mgr.WriteSessionWorkspaceFile(ctx, sessionID, p, data); retryErr != nil {\n        return fmt.Errorf(\"persist workspace file %s: %w\", p, retryErr)\n    }\n}","preventionTips":["Persist model outputs soon after generation to avoid sandbox expiry mid-flight.","Set generous HTTP timeouts for large writes.","Monitor provider rate limits and back off on 429.","Keep workspace write paths within the sanitized workspace root."],"tags":["go","sandbox","file-upload","network"],"backgroundTag":"remote-file-write-failed","analyzedSha":"988cbb03305e055d8ebb7d46d9ac6cc0803cd074","analyzedAt":"2026-09-02T14:41:08.344Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}