iflytek/astron-agent · error · BusinessException

WORKFLOW_NOT_EXIST

WORKFLOW_NOT_EXIST

Error message

BusinessException(ResponseEnum.WORKFLOW_NOT_EXIST)

What it means

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.

Solutions

  1. Verify the flowId exists and deleted=false in the workflow table for that space.
  2. Fetch the correct flowId from the workflow list/detail API instead of reusing an old id.
  3. Re-create the workflow if it was deleted and re-provision the sandbox config against the new flowId.
  4. Check for duplicate flowId rows and dedupe if the limit-2 guard was actually hit.

Example fix

// before
getRuntimeCredential(token, "flow-abc-old", uid, spaceId);
// after
WorkflowDto wf = workflowClient.list(spaceId).stream()
    .filter(w -> !w.isDeleted() && "new-flow-id".equals(w.getFlowId()))
    .findFirst().orElseThrow();
getRuntimeCredential(token, wf.getFlowId(), uid, spaceId);
Defensive patterns

Strategy: validation

Validate before calling

WorkflowDto wf = workflowClient.findActiveByFlowId(flowId);
if (wf == null || wf.isDeleted()) throw new IllegalArgumentException("flowId not active: " + flowId);

Try / catch

try {
    cred = getRuntimeCredential(token, flowId, uid, spaceId);
} catch (BusinessException e) {
    if ("WORKFLOW_NOT_EXIST".equals(e.getCode())) refreshFlowIdFromRegistry();
}

Prevention

When it happens

Trigger: Calling getRuntimeCredential with a flowId that matches no workflow, a workflow marked deleted=true, or (theoretically) a duplicate flowId yielding two rows.

Common situations: 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.

Understand the failure class

Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.

Related errors


AI-assisted analysis of iflytek/astron-agent@5e758547a8 (2026-09-12). Data as JSON: /api/errors/d9ef9aa96e050063. Report an issue: GitHub.

Appendix: source

Thrown at console/backend/toolkit/src/main/java/com/iflytek/astron/console/toolkit/service/skill/SkillSandboxConfigService.java:144

     * derives scope from the database; standalone agent calls must provide a currently authorized
     * uid/space pair.
     */
    public SkillSandboxRuntimeCredentialDto getRuntimeCredential(
            String serviceToken, String flowId, String uid, Long spaceId) {
        if (runtimeCredentialTokenProvider == null
                || !runtimeCredentialTokenProvider.matches(serviceToken)) {
            throw new BusinessException(ResponseEnum.UNAUTHORIZED);
        }
        assertExplicitScope(uid, spaceId);
        SkillSandboxConfig config;
        if (StringUtils.isNotBlank(flowId)) {
            List<Workflow> workflows = workflowMapper.selectList(
                    Wrappers.lambdaQuery(Workflow.class)
                            .eq(Workflow::getFlowId, StringUtils.trim(flowId))
                            .eq(Workflow::getDeleted, Boolean.FALSE)
                            .last("limit 2"));
            if (workflows == null || workflows.size() != 1) {
                throw new BusinessException(ResponseEnum.WORKFLOW_NOT_EXIST);
            }
            Workflow workflow = workflows.getFirst();
            assertWorkflowExecutionScope(workflow, uid, spaceId);
            config = getActiveConfigForTrustedScope(workflow.getUid(), workflow.getSpaceId());
        } else {
            config = getActiveConfigForTrustedScope(uid, spaceId);
        }
        if (config == null) {
            throw new BusinessException(ResponseEnum.DATA_NOT_EXIST);
        }
        return new SkillSandboxRuntimeCredentialDto(
                normalizeProvider(config.getProvider()),
                config.getApiKey(),
                normalizeTimeout(config.getTimeoutSeconds()),
                Boolean.TRUE.equals(config.getAllowInternetAccess()));
    }

    private void assertWorkflowExecutionScope(Workflow workflow, String uid, Long spaceId) {

View on GitHub (pinned to 5e758547a8)