{"record":{"id":"b53b79efcb139cee","repo":"Tencent/WeKnora","slug":"sandbox-s-backend-must-be-constructed-via-newses","errorCode":null,"errorMessage":"sandbox: %s backend must be constructed via NewSessionBoundManager","messagePattern":"sandbox: (.+?) backend must be constructed via NewSessionBoundManager","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/sandbox/manager.go","lineNumber":56,"sourceCode":"\t}\n\n\treturn manager, nil\n}\n\n// initializeSandbox creates and configures the sandbox based on configuration\nfunc (m *DefaultManager) initializeSandbox(ctx context.Context) error {\n\tswitch m.config.Type {\n\tcase SandboxTypeDisabled:\n\t\tm.sandbox = &disabledSandbox{}\n\t\treturn nil\n\n\tcase SandboxTypeCube, SandboxTypeE2B, SandboxTypeDocker:\n\t\t// Session-scoped remote backends are only reachable through\n\t\t// SessionBoundManager, which owns the authoritative binding.\n\t\t// DefaultManager exposes stateless semantics that cannot preserve\n\t\t// per-session state, so we refuse the construction and let\n\t\t// NewManagerFromType route the caller to NewSessionBoundManager.\n\t\treturn fmt.Errorf(\n\t\t\t\"sandbox: %s backend must be constructed via NewSessionBoundManager\",\n\t\t\tm.config.Type,\n\t\t)\n\n\tdefault:\n\t\treturn fmt.Errorf(\"unknown sandbox type: %s\", m.config.Type)\n\t}\n}\n\n// Execute runs a script using the configured sandbox\n// It performs security validation before execution to prevent prompt injection attacks\nfunc (m *DefaultManager) Execute(ctx context.Context, config *ExecuteConfig) (*ExecuteResult, error) {\n\tm.mu.RLock()\n\tsandbox := m.sandbox\n\tm.mu.RUnlock()\n\n\tif sandbox == nil {\n\t\treturn nil, ErrSandboxDisabled","sourceCodeStart":38,"sourceCodeEnd":74,"githubUrl":"https://github.com/Tencent/WeKnora/blob/988cbb03305e055d8ebb7d46d9ac6cc0803cd074/internal/sandbox/manager.go#L38-L74","documentation":"DefaultManager.initializeSandbox refuses remote, session-scoped backends (Cube, E2B, Docker). These backends need per-session state that only SessionBoundManager owns via its authoritative session binding, so DefaultManager intentionally rejects them and points the caller at NewSessionBoundManager (which NewManagerFromType routes to automatically).","triggerScenarios":"Calling NewManager with a Config whose Type is SandboxTypeCube, SandboxTypeE2B, or SandboxTypeDocker; NewManager then fails during initializeSandbox.","commonSituations":"Choosing the wrong constructor: using NewManager instead of NewManagerFromType for remote sandbox types; older code written before session-bound managers existed; test code copying a config from a remote deployment into NewManager.","solutions":["Use NewManagerFromType(\"cube\"|\"e2b\"|\"docker\", dockerImage) which routes remote types to NewSessionBoundManager.","Call NewSessionBoundManager directly with the required session binding configuration.","If you only need the default manager, set config.Type to a stateless-supported type (e.g. local/disabled).","Refactor call sites to pick the manager constructor based on backend type."],"exampleFix":"// before\nconfig := DefaultConfig(); config.Type = SandboxTypeE2B\nmgr, err := NewManager(config)\n// after\nmgr, err := NewManagerFromType(\"e2b\", \"\") // routes to NewSessionBoundManager","handlingStrategy":"validation","validationCode":"switch cfg.Type {\ncase SandboxTypeCube, SandboxTypeE2B, SandboxTypeDocker:\n    return errors.New(\"use NewManagerFromType / NewSessionBoundManager for this backend\")\n}","typeGuard":"func needsSessionBound(t SandboxType) bool {\n    switch t {\n    case SandboxTypeCube, SandboxTypeE2B, SandboxTypeDocker:\n        return true\n    }\n    return false\n}","tryCatchPattern":"mgr, err := NewManager(cfg)\nif err != nil && strings.Contains(err.Error(), \"NewSessionBoundManager\") {\n    mgr, err = NewManagerFromType(string(cfg.Type), \"\")\n}","preventionTips":["Route remote backend types exclusively through NewManagerFromType","Document that DefaultManager is for stateless backends only","Add unit tests asserting constructor choice per sandbox type"],"tags":["sandbox","architecture","session"],"backgroundTag":"unsupported-constructor","analyzedSha":"988cbb03305e055d8ebb7d46d9ac6cc0803cd074","analyzedAt":"2026-09-02T14:41:08.344Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}