{"record":{"id":"18c95ee946d5b5dd","repo":"alibaba/spring-ai-alibaba","slug":"requestcontext-workspaceid-workspace","errorCode":null,"errorMessage":"无法获取 RequestContext 的 workspaceId，将不使用 workspace 过滤: {}","messagePattern":"无法获取 RequestContext 的 workspaceId，将不使用 workspace 过滤: (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"spring-ai-alibaba-admin/spring-ai-alibaba-admin-server-start/src/main/java/com/alibaba/cloud/ai/studio/admin/utils/ModelConfigParser.java","lineNumber":69,"sourceCode":"        try {\n            modelConfigInfo = parseModelConfig(modelConfig);\n            validateModelConfig(modelConfigInfo);\n            \n            // 验证模型配置是否存在\n            // 首先尝试从 ModelConfigRepository (YAML 文件) 查找\n            boolean exists = modelConfigRepository.existsById(modelConfigInfo.getModelId());\n            \n            if (!exists) {\n                // 如果 ModelConfigRepository 中不存在，尝试从 ModelManager (数据库) 查找\n                // 安全地获取 workspaceId\n                String workspaceId = null;\n                try {\n                    RequestContext context = RequestContextHolder.getRequestContext();\n                    if (context != null) {\n                        workspaceId = context.getWorkspaceId();\n                    }\n                } catch (Exception e) {\n                    log.warn(\"无法获取 RequestContext 的 workspaceId，将不使用 workspace 过滤: {}\", e.getMessage());\n                }\n                \n                ModelEntity modelEntity = null;\n                \n                // 1. 首先尝试通过 modelId (Long) 作为 ModelEntity 的 id 查找\n                if (modelConfigInfo.getModelId() != null) {\n                    modelEntity = modelManager.findModelByIdOrName(modelConfigInfo.getModelId(), workspaceId);\n                }\n                \n                // 2. 如果通过 modelId 找不到，尝试通过 modelName 查找\n                if (modelEntity == null) {\n                    String modelName = (String) modelConfigInfo.getParameter(\"modelName\");\n                    if (StringUtils.hasText(modelName)) {\n                        modelEntity = modelManager.findModelByIdOrName(modelName, workspaceId);\n                    }\n                }\n                \n                // 3. 如果还是找不到，抛出异常","sourceCodeStart":51,"sourceCodeEnd":87,"githubUrl":"https://github.com/alibaba/spring-ai-alibaba/blob/f82da0b50f35744c13968191be2b1cd2452ef550/spring-ai-alibaba-admin/spring-ai-alibaba-admin-server-start/src/main/java/com/alibaba/cloud/ai/studio/admin/utils/ModelConfigParser.java#L51-L87","documentation":"ModelConfigParser.checkAndGetModelConfigInfo attempts to read the workspaceId from RequestContextHolder.getRequestContext() to scope the model lookup; if obtaining the context throws, it logs this warning and proceeds WITHOUT workspace filtering. Model resolution then searches across all workspaces, which can resolve an unintended model or leak cross-workspace configs.","triggerScenarios":"Calling checkAndGetModelConfigInfo outside a request-scoped context (async thread, scheduler, startup code, tests) where RequestContextHolder.getRequestContext() throws or is unavailable.","commonSituations":"Invoking model resolution from @Async methods or thread pools where the request context is not propagated; unit/integration tests without a mocked RequestContext; background jobs resolving model configs.","solutions":["Propagate the RequestContext to the worker thread (context-propagating executor or explicit pass-through)","Pass workspaceId explicitly to the model lookup instead of relying on the request context holder","In tests, set up a RequestContext in the holder before invoking the parser","If cross-workspace resolution is unacceptable, treat the missing context as an error rather than a warning"],"exampleFix":"// before\nRequestContext ctx = RequestContextHolder.getRequestContext(); // throws on async thread\n// after\nRequestContext ctx = contextSupplier.get();\nif (ctx == null) { throw new IllegalStateException(\"workspaceId required for model lookup\"); }","handlingStrategy":"fallback","validationCode":"RequestContext ctx = RequestContextHolder.getRequestContext(); if (ctx == null || ctx.getWorkspaceId() == null) { throw new IllegalStateException(\"workspaceId unavailable\"); }","typeGuard":null,"tryCatchPattern":"try { parse(config); } catch (MissingWorkspaceException e) { resolveWithExplicitWorkspaceId(wsId, config); }","preventionTips":["Propagate RequestContext into async threads and pools","Pass workspaceId explicitly where possible","Set up request context in tests","Fail fast when workspace scoping is mandatory"],"tags":["request-context","workspace","threading"],"backgroundTag":"missing-config-value","analyzedSha":"f82da0b50f35744c13968191be2b1cd2452ef550","analyzedAt":"2026-09-09T15:32:42.421Z","contentChangedAt":"2026-09-09T15:32:42.421Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}