iflytek/astron-agent · warning

Parse generated skill metadata failed

Error message

Parse generated skill metadata failed

What it means

parseGeneratedMetadata takes the LLM's free-text response and extracts a valid skill name and description (with length clamping). If the content is null, unparseable, or the name fails isValidSkillName, the catch logs this warning (no workflow ID here) and returns null, causing the caller to use fallback metadata.

Solutions

  1. Tighten buildMetadataPrompt to demand strict output format and add an example, improving parse success rate
  2. Make parseGeneratedMetadata tolerant: strip markdown fences, trim, and accept more name characters in isValidSkillName
  3. Log the raw model content (truncated) at debug level to diagnose recurring parse failures
  4. If name validation rejects, sanitize (strip illegal chars, truncate) instead of discarding entirely

Example fix

// before
return new SkillMetadata(name, description, true);
} catch (Exception e) {
    log.warn("Parse generated skill metadata failed");
    return null;
}
// after
} catch (Exception e) {
    log.warn("Parse generated skill metadata failed, rawContent={}", StringUtils.abbreviate(raw, 200), e);
    return sanitizeOrFallback(raw);
}
Defensive patterns

Strategy: fallback

Validate before calling

// pre-validate model output shape before detailed parsing
if (content == null || content.isBlank()) return null;
if (!content.contains("name") && !content.contains("description")) return null;

Type guard

SkillMetadata tryParse(String raw) {
    if (raw == null || raw.isBlank()) return null;
    String cleaned = raw.replaceAll("^```.*?\\n|```$", "").trim();
    return parseGeneratedMetadata(cleaned);
}

Try / catch

SkillMetadata meta = parseGeneratedMetadata(content);
if (meta == null) {
    log.warn("Parse generated skill metadata failed, falling back for workflowId={}", workflowId);
    meta = fallback;
}

Prevention

When it happens

Trigger: generated LLM content does not match the expected format the parser expects — empty content after timeout/exception, model returning prose instead of the requested structured name/description, or name failing isValidSkillName (blank, invalid characters, too long).

Common situations: Model ignoring output-format instructions; responses in another language or wrapped in markdown the parser can't strip; overly long generated names rejected by validation; LLM returning refusal/error text instead of metadata.

Related errors


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

Appendix: source

Thrown at console/backend/hub/src/main/java/com/iflytek/astron/console/hub/service/workflow/impl/WorkflowSkillExportServiceImpl.java:182

        int start = content.indexOf('{');
        int end = content.lastIndexOf('}');
        if (start < 0 || end <= start) {
            return null;
        }

        try {
            JSONObject json = JSON.parseObject(content.substring(start, end + 1));
            String name = StringUtils.trim(json.getString("name"));
            String description = StringUtils.trim(json.getString("description"));
            if (!isValidSkillName(name) || StringUtils.isBlank(description)) {
                return null;
            }
            if (description.length() > SKILL_DESCRIPTION_MAX_LENGTH) {
                description = description.substring(0, SKILL_DESCRIPTION_MAX_LENGTH);
            }
            return new SkillMetadata(name, description, true);
        } catch (Exception e) {
            log.warn("Parse generated skill metadata failed");
            return null;
        }
    }

    private boolean isValidSkillName(String name) {
        return StringUtils.isNotBlank(name)
                && name.length() <= SKILL_NAME_MAX_LENGTH
                && name.matches("[a-z0-9][a-z0-9-]*");
    }

    private String toSkillName(String workflowName, Long workflowId) {
        String normalizedText = Normalizer.normalize(
                StringUtils.defaultString(workflowName),
                Normalizer.Form.NFKD);
        StringBuilder normalizedBuilder = new StringBuilder(normalizedText.length());
        boolean previousHyphen = false;
        for (int i = 0; i < normalizedText.length(); i++) {
            char current = normalizedText.charAt(i);

View on GitHub (pinned to 5e758547a8)