apache/seatunnel · error · CommandExecuteException

Failed to export metadata

Error message

Failed to export metadata

What it means

MetadataExportCommand.execute writes the exported connector metadata (plugin identifiers, option rules) to the output JSON file. Any IOException encountered while creating or writing that file is rethrown as CommandExecuteException('Failed to export metadata', e). The export logic itself succeeded in enumerating connectors; the failure is purely on the output-file side.

Source

Thrown at seatunnel-core/seatunnel-starter/src/main/java/org/apache/seatunnel/core/starter/seatunnel/command/MetadataExportCommand.java:134

                    connectorsArray.add(connectorNode);
                }
            }

            root.set("connectors", connectorsArray);

            if (args.isStdout()) {
                System.out.println(mapper.writeValueAsString(root));
            } else {
                File outputFile = new File(args.getOutputPath());
                mapper.writeValue(outputFile, root);
                System.err.println(
                        "Exported "
                                + connectorsArray.size()
                                + " connectors to "
                                + outputFile.getAbsolutePath());
            }
        } catch (IOException e) {
            throw new CommandExecuteException("Failed to export metadata", e);
        }
    }

    private ObjectNode exportConnector(
            PluginIdentifier id, OptionRule rule, PluginType pluginType) {
        ObjectNode node = mapper.createObjectNode();
        node.put("name", id.getPluginName());
        node.put("type", pluginType.getType());

        // Required options — preserving the 4 subtypes
        ArrayNode requiredArray = mapper.createArrayNode();
        for (RequiredOption reqOpt : rule.getRequiredOptions()) {
            String category = resolveCategory(reqOpt);
            String expression = null;

            if (reqOpt instanceof RequiredOption.ConditionalRequiredOptions) {
                Expression expr =
                        ((RequiredOption.ConditionalRequiredOptions) reqOpt).getExpression();

View on GitHub (pinned to cf67b549a7)

Solutions

  1. Check the nested IOException cause for the exact filesystem reason.
  2. Verify the output path's parent directory exists and is writable by the running user; create it or choose another path.
  3. Check disk space and file permissions (ls -ld on the target directory).
  4. If running in a container, ensure the volume is mounted and the user has write access.

Example fix

// before
seatunnel.sh -m --output /root/only/meta.json   # non-root user
// after
mkdir -p /tmp/seatunnel-meta
seatunnel.sh -m --output /tmp/seatunnel-meta/meta.json
Defensive patterns

Strategy: validation

Validate before calling

const dir = path.dirname(outputFile);
if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
fs.accessSync(dir, fs.constants.W_OK); // throws early if unwritable

Try / catch

try { exportMetadata(args); } catch (CommandExecuteException e) { if (e.getMessage().equals("Failed to export metadata")) { log.error("Check output path/permissions/disk: ", e.getCause()); } else { throw e; } }

Prevention

When it happens

Trigger: The --output path is unwritable (permission denied, read-only filesystem), its parent directory does not exist, the path is a directory, or disk is full while the Jackson writer flushes the connectors array.

Common situations: Running in a container as non-root writing to a root-owned path; typo in the output directory; overwriting a file locked or owned by another user; exporting to a mounted volume not yet mounted.

Understand the failure class

Background: "failed to write file", "Could not save figure", "Error saving remote file" — file write failed: causes and fixes across languages and libraries — this error's family across 38 libraries.

Related errors


AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10). Data as JSON: /api/errors/bbfde83ac34b9ead. Report an issue: GitHub.