quarkusio/quarkus · error · IOException

quarkus-extension.yaml is empty or contains no object

Error message

quarkus-extension.yaml is empty or contains no object

What it means

SkillComposer.parseExtensionMetadata(InputStream) deserializes quarkus-extension.yaml into a Jackson ObjectNode. If YAML_MAPPER.readValue returns null — meaning the stream was empty or contained no YAML object — it throws IOException("quarkus-extension.yaml is empty or contains no object") because downstream skill composition requires extension metadata.

Source

Thrown at independent-projects/tools/devtools-common/src/main/java/io/quarkus/devtools/utils/SkillComposer.java:52

    /**
     * Returns the output path for a composed skill file inside the deployment JAR,
     * following the Agent Skills directory convention.
     *
     * @param skillName the skill identifier (e.g. {@code quarkus-arc})
     */
    public static String outputSkillPath(String skillName) {
        return "META-INF/skills/" + skillName + "/SKILL.md";
    }

    /**
     * Parses a {@code quarkus-extension.yaml} from the given input stream.
     *
     * @throws IOException if the stream cannot be read, the YAML is malformed, or the file is empty
     */
    public static ObjectNode parseExtensionMetadata(InputStream is) throws IOException {
        final ObjectNode result = YAML_MAPPER.readValue(is, ObjectNode.class);
        if (result == null) {
            throw new IOException("quarkus-extension.yaml is empty or contains no object");
        }
        return result;
    }

    /**
     * Composes a skill document from extension metadata and raw skill content,
     * producing a {@code SKILL.md} file with YAML frontmatter per the
     * <a href="https://agentskills.io/specification">Agent Skills specification</a>.
     *
     * @param extMeta the parsed {@code quarkus-extension.yaml} as an {@link ObjectNode}
     * @param rawContent the raw skill file content authored by the extension developer
     * @param skillName the skill identifier used in the frontmatter {@code name} field
     *        (e.g. {@code quarkus-arc}, derived from the runtime artifact name)
     * @param license the SPDX license identifier (e.g. {@code Apache-2.0}), may be {@code null}
     */
    public static String compose(ObjectNode extMeta, String rawContent, String skillName, String license) {
        Objects.requireNonNull(extMeta, "extMeta must not be null");
        Objects.requireNonNull(rawContent, "rawContent must not be null");

View on GitHub (pinned to e1c734241f)

Solutions

  1. Verify the quarkus-extension.yaml exists and has non-empty object content in the source JAR/directory.
  2. Rebuild the extension (mvn install) so the extension descriptor is regenerated.
  3. Check that the InputStream is positioned at the start and actually delivers bytes (not already consumed).
  4. Validate the YAML parses to an object (e.g. with a quick YAML parser) before composing the skill.

Example fix

// before: empty/invalid descriptor
// quarkus-extension.yaml: (0 bytes)
// after: minimal valid descriptor
artifact: "${project.groupId}:${project.artifactId}::jar:${project.version}"
name: "My Extension"
metadata:
  unlisted: true
Defensive patterns

Strategy: validation

Validate before calling

byte[] bytes = is.readAllBytes();
if (bytes.length == 0) {
    throw new IOException("quarkus-extension.yaml is empty");
}
ObjectNode node = SkillComposer.parseExtensionMetadata(new ByteArrayInputStream(bytes));

Type guard

static boolean hasExtensionMetadata(InputStream is) throws IOException {
    try (is) {
        return is.read() != -1; // non-empty stream
    }
}

Try / catch

try {
    ObjectNode meta = SkillComposer.parseExtensionMetadata(is);
} catch (IOException e) {
    if (e.getMessage() != null && e.getMessage().contains("empty")) {
        log.error("Descriptor empty; rebuild the extension JAR to regenerate quarkus-extension.yaml");
    }
}

Prevention

When it happens

Trigger: Calling parseExtensionMetadata with an InputStream whose content is empty, whitespace-only, or parses to no object (null) — e.g. reading a quarkus-extension.yaml that was truncated to zero bytes or contains only comments.

Common situations: A built/installed extension JAR contains an empty quarkus-extension.yaml because the extension processor failed to generate it; a file was truncated during copy/deployment; a hand-edited metadata file had its content wiped; reading from a stream already consumed or closed upstream yielding empty input.

Related errors


AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05). Data as JSON: /api/errors/1cb04b4cb9dfd53e. Report an issue: GitHub.