{"record":{"id":"d9ef9aa96e050063","repo":"iflytek/astron-agent","slug":"workflow-not-exist","errorCode":"WORKFLOW_NOT_EXIST","errorMessage":"BusinessException(ResponseEnum.WORKFLOW_NOT_EXIST)","messagePattern":"BusinessException\\(ResponseEnum\\.WORKFLOW_NOT_EXIST\\)","errorType":"error_code","errorClass":"BusinessException","httpStatus":null,"severity":"error","filePath":"console/backend/toolkit/src/main/java/com/iflytek/astron/console/toolkit/service/skill/SkillSandboxConfigService.java","lineNumber":144,"sourceCode":"     * derives scope from the database; standalone agent calls must provide a currently authorized\n     * uid/space pair.\n     */\n    public SkillSandboxRuntimeCredentialDto getRuntimeCredential(\n            String serviceToken, String flowId, String uid, Long spaceId) {\n        if (runtimeCredentialTokenProvider == null\n                || !runtimeCredentialTokenProvider.matches(serviceToken)) {\n            throw new BusinessException(ResponseEnum.UNAUTHORIZED);\n        }\n        assertExplicitScope(uid, spaceId);\n        SkillSandboxConfig config;\n        if (StringUtils.isNotBlank(flowId)) {\n            List<Workflow> workflows = workflowMapper.selectList(\n                    Wrappers.lambdaQuery(Workflow.class)\n                            .eq(Workflow::getFlowId, StringUtils.trim(flowId))\n                            .eq(Workflow::getDeleted, Boolean.FALSE)\n                            .last(\"limit 2\"));\n            if (workflows == null || workflows.size() != 1) {\n                throw new BusinessException(ResponseEnum.WORKFLOW_NOT_EXIST);\n            }\n            Workflow workflow = workflows.getFirst();\n            assertWorkflowExecutionScope(workflow, uid, spaceId);\n            config = getActiveConfigForTrustedScope(workflow.getUid(), workflow.getSpaceId());\n        } else {\n            config = getActiveConfigForTrustedScope(uid, spaceId);\n        }\n        if (config == null) {\n            throw new BusinessException(ResponseEnum.DATA_NOT_EXIST);\n        }\n        return new SkillSandboxRuntimeCredentialDto(\n                normalizeProvider(config.getProvider()),\n                config.getApiKey(),\n                normalizeTimeout(config.getTimeoutSeconds()),\n                Boolean.TRUE.equals(config.getAllowInternetAccess()));\n    }\n\n    private void assertWorkflowExecutionScope(Workflow workflow, String uid, Long spaceId) {","sourceCodeStart":126,"sourceCodeEnd":162,"githubUrl":"https://github.com/iflytek/astron-agent/blob/5e758547a83371a5a4b29dadf4ac03e8dd527635/console/backend/toolkit/src/main/java/com/iflytek/astron/console/toolkit/service/skill/SkillSandboxConfigService.java#L126-L162","documentation":"When resolving runtime credentials by flowId, getRuntimeCredential queries the workflow table (flowId match, not deleted, limit 2) and requires exactly one matching row. Zero or two matches cause WORKFLOW_NOT_EXIST. This guards against ambiguous or nonexistent workflow identifiers.","triggerScenarios":"Calling getRuntimeCredential with a flowId that matches no workflow, a workflow marked deleted=true, or (theoretically) a duplicate flowId yielding two rows.","commonSituations":"Sandbox passing a flowId of a workflow that was deleted or hard-removed by cleanup; passing a draft/local id not yet persisted; leading/trailing whitespace differences (service trims, caller may use a padded id) or wrong id from a test client.","solutions":["Verify the flowId exists and deleted=false in the workflow table for that space.","Fetch the correct flowId from the workflow list/detail API instead of reusing an old id.","Re-create the workflow if it was deleted and re-provision the sandbox config against the new flowId.","Check for duplicate flowId rows and dedupe if the limit-2 guard was actually hit."],"exampleFix":"// before\ngetRuntimeCredential(token, \"flow-abc-old\", uid, spaceId);\n// after\nWorkflowDto wf = workflowClient.list(spaceId).stream()\n    .filter(w -> !w.isDeleted() && \"new-flow-id\".equals(w.getFlowId()))\n    .findFirst().orElseThrow();\ngetRuntimeCredential(token, wf.getFlowId(), uid, spaceId);","handlingStrategy":"validation","validationCode":"WorkflowDto wf = workflowClient.findActiveByFlowId(flowId);\nif (wf == null || wf.isDeleted()) throw new IllegalArgumentException(\"flowId not active: \" + flowId);","typeGuard":null,"tryCatchPattern":"try {\n    cred = getRuntimeCredential(token, flowId, uid, spaceId);\n} catch (BusinessException e) {\n    if (\"WORKFLOW_NOT_EXIST\".equals(e.getCode())) refreshFlowIdFromRegistry();\n}","preventionTips":["Resolve flowId dynamically from the workflow API instead of hard-coding.","Treat deleted workflows as permanently invalid; never retry with the same id.","Check for duplicate flowId constraints in the workflow table."],"tags":["java","workflow","not-found","database"],"backgroundTag":"entity-not-found","analyzedSha":"5e758547a83371a5a4b29dadf4ac03e8dd527635","analyzedAt":"2026-09-12T08:03:51.356Z","contentChangedAt":"2026-09-12T08:03:51.356Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}