iflytek/astron-agent · error · BusinessException

NO_WORKFLOW

NO_WORKFLOW

Error message

ResponseEnum.NO_WORKFLOW

What it means

NO_WORKFLOW (distinct from WORKFLOW_NOT_EXIST) is thrown by getInputsType when no workflow row matches the given flowId via the flowId equality query. The service logs 'Flow not found' with the id and fails fast rather than returning null inputs.

Solutions

  1. Verify the flowId exists in the workflow table (query eq flow_id, deleted=false) before calling; list workflows in the space to find the correct one
  2. Fix the client/config that supplies the flowId (trim/normalize the string, use the id returned at creation time)
  3. If the workflow was deleted, recreate it or use a still-existing flowId
  4. Catch BusinessException code NO_WORKFLOW and return 404 'flow not found' including the flowId for debugging

Example fix

// before
service.getInputsType("wf-abc"); // typo -> throws NO_WORKFLOW
// after
Workflow wf = workflowService.getOne(Wrappers.lambdaQuery(Workflow.class)
        .eq(Workflow::getFlowId, "wf-abc").eq(Workflow::getDeleted, false));
if (wf == null) {
    throw new BusinessException(ResponseEnum.NO_WORKFLOW);
}
service.getInputsType("wf-abc");
Defensive patterns

Strategy: validation

Validate before calling

Workflow wf = workflowService.getOne(Wrappers.lambdaQuery(Workflow.class)
        .eq(Workflow::getFlowId, flowId).eq(Workflow::getDeleted, false));
if (wf == null) { throw new BusinessException(ResponseEnum.NO_WORKFLOW); }

Type guard

boolean flowExists(String flowId) { return flowId != null && !flowId.isBlank()
        && workflowService.getOne(Wrappers.lambdaQuery(Workflow.class).eq(Workflow::getFlowId, flowId)) != null; }

Try / catch

try { service.getInputsType(flowId); } catch (BusinessException e) { if (code==NO_WORKFLOW) { /* 404 with flowId */ } else throw e; }

Prevention

When it happens

Trigger: Calling getInputsType(flowId) with a flowId string that matches no row — typo'd id, flowId from a deleted workflow, flowId from another environment/tenant, or duplicated rows making getOne behavior ambiguous/returning null on no match.

Common situations: Client storing flowIds after workflows were deleted; cross-environment configuration pointing at the wrong DB; case/whitespace mismatch in the flowId string; tenant isolation filtering out the row.

Understand the failure class

Background: Record Not Found Errors: "not found", RecordNotFound, and "was not found" — what they mean and how to fix them — this error's family across 28 libraries.

Related errors


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

Appendix: source

Thrown at console/backend/toolkit/src/main/java/com/iflytek/astron/console/toolkit/service/workflow/WorkflowService.java:4709

        all.addAll(llm);
        all.addAll(intent);
        // all.addAll(vExtractor);

        return all;
    }


    public Object evalPageFirstTime(Long id) {
        return update(Wrappers.lambdaUpdate(Workflow.class)
                .eq(Workflow::getId, id)
                .set(Workflow::getEvalPageFirstTime, false));
    }

    public Object getInputsType(String flowId) {
        Workflow workflow = getOne(Wrappers.lambdaQuery(Workflow.class).eq(Workflow::getFlowId, flowId));
        if (workflow == null) {
            log.error("Flow not found, id=" + flowId);
            throw new BusinessException(ResponseEnum.NO_WORKFLOW);
        }

        String data = workflow.getData();
        if (StringUtils.isBlank(data)) {
            log.error("Workflow protocol is empty, id=" + flowId);
            throw new BusinessException(ResponseEnum.WORKFLOW_PROTOCOL_EMPTY);
        }

        BizWorkflowData bizWorkflowData = JSON.parseObject(data, BizWorkflowData.class);
        List<BizWorkflowNode> nodes = bizWorkflowData.getNodes();
        for (BizWorkflowNode node : nodes) {
            if (node.getId().startsWith(WorkflowConst.NodeType.START)) {
                // Parse input
                List<BizInputOutput> outputs = node.getData().getOutputs();
                return JsonConverter.flowInputTypeConvert(JSON.toJSONString(outputs));
            }
        }

View on GitHub (pinned to 5e758547a8)