{"record":{"id":"0595491e48ac2efa","repo":"Tencent/WeKnora","slug":"cube-remote-client-config-is-required","errorCode":null,"errorMessage":"cube remote client config is required","messagePattern":"cube remote client config is required","errorType":"validation","errorClass":null,"httpStatus":400,"severity":"error","filePath":"internal/sandbox/cube_remote_client.go","lineNumber":52,"sourceCode":"// NewCubeRemoteClient constructs a Cube-backed RemoteSandboxClient using the\n// SDK default HTTP clients (separate control/data pools). Suitable for the\n// process-wide default manager and for throwaway connectivity probes, neither\n// of which benefits from an externally owned pool.\nfunc NewCubeRemoteClient(config *Config) (*CubeRemoteClient, error) {\n\treturn NewCubeRemoteClientWithPool(config, nil)\n}\n\n// NewCubeRemoteClientWithPool builds a client whose connections come from a\n// caller-owned pool. Named configs construct a client per request, so the pool\n// is what keeps connections alive across requests; it routes control-plane\n// traffic onto the transport shared with E2B while preserving the SDK's\n// proxy dial rewrite for the data plane. A nil pool keeps the SDK defaults.\nfunc NewCubeRemoteClientWithPool(\n\tconfig *Config,\n\tpool *SandboxGatewayTransportPool,\n) (*CubeRemoteClient, error) {\n\tif config == nil {\n\t\treturn nil, errors.New(\"cube remote client config is required\")\n\t}\n\thttpTimeout := config.CubeHTTPTimeout\n\tif httpTimeout <= 0 {\n\t\thttpTimeout = DefaultCubeHTTPTimeout\n\t}\n\tsdkCfg := cubesandbox.Config{\n\t\tAPIURL:         config.CubeAPIURL,\n\t\tAPIKey:         config.CubeAPIKey,\n\t\tTemplateID:     config.CubeTemplate,\n\t\tSandboxDomain:  config.CubeSandboxDomain,\n\t\tTimeout:        config.CubeHTTPTimeout,\n\t\tRequestTimeout: config.CubeHTTPTimeout,\n\t}\n\n\tif proxyHost, proxyPort, proxyScheme, ok := parseProxyURL(config.CubeProxyURL); ok {\n\t\tsdkCfg.ProxyNodeIP = proxyHost\n\t\tsdkCfg.ProxyPortHTTP = proxyPort\n\t\tsdkCfg.ProxyScheme = proxyScheme","sourceCodeStart":34,"sourceCodeEnd":70,"githubUrl":"https://github.com/Tencent/WeKnora/blob/988cbb03305e055d8ebb7d46d9ac6cc0803cd074/internal/sandbox/cube_remote_client.go#L34-L70","documentation":"NewCubeRemoteClientWithPool requires a non-nil *Config; passing nil means the client has no provider settings (timeout, endpoint, credentials) and cannot be constructed. This is a programmer-error guard at the constructor boundary.","triggerScenarios":"Calling NewCubeRemoteClient, buildClient, or NewRemoteForCheck when the resolved sandbox *Config is nil — e.g. config lookup returned (nil, nil), a check/health-probe path skipped config resolution, or a test constructed the client directly without a config.","commonSituations":"Tenant sandbox config missing so resolution silently yields nil; refactors changing NewCubeRemoteClient to pass through an optional config; health-check endpoints probing before configuration exists.","solutions":["Resolve the tenant's sandbox config first and handle the missing-config case before constructing the client.","At call sites, check for nil config and return a config-incomplete error (map to 400) instead of calling the constructor.","If the config may legitimately be absent, gate construction behind sandbox config presence (RequireCompleteConfig).","In tests, always construct a valid &sandbox.Config{} rather than nil."],"exampleFix":"// before\ncfg, _ := resolveSandboxConfig(ctx, tenantID)\nclient, err := sandbox.NewCubeRemoteClient(cfg) // panics into error if cfg nil\n// after\ncfg, err := resolveSandboxConfig(ctx, tenantID)\nif err != nil || cfg == nil {\n    return nil, sandbox.ErrSandboxConfigIncomplete\n}\nclient, err := sandbox.NewCubeRemoteClient(cfg)","handlingStrategy":"validation","validationCode":"cfg, err := resolveSandboxConfig(ctx, tenantID)\nif err != nil {\n    return nil, err\n}\nif cfg == nil {\n    return nil, sandbox.ErrSandboxConfigIncomplete\n}\nclient, err := sandbox.NewCubeRemoteClient(cfg)","typeGuard":"func canBuildCubeClient(cfg *sandbox.Config) bool { return cfg != nil }","tryCatchPattern":"client, err := sandbox.NewCubeRemoteClient(cfg)\nif err != nil {\n    if strings.Contains(err.Error(), \"config is required\") {\n        return nil, fmt.Errorf(\"sandbox not configured for tenant: %w\", err)\n    }\n    return nil, err\n}","preventionTips":["Never ignore the error from config resolution; a (nil, nil) result still needs handling.","Gate client construction behind RequireCompleteConfig.","Construct configs explicitly in tests instead of passing nil."],"tags":["sandbox","nil-config","constructor"],"backgroundTag":"nil-config-argument","analyzedSha":"988cbb03305e055d8ebb7d46d9ac6cc0803cd074","analyzedAt":"2026-09-02T14:41:08.344Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}