SonarSource/sonarqube · error · IllegalStateException
Metadata has already been written
Error message
Metadata has already been written
What it means
DumpWriterImpl.write(ProjectDump.Metadata) writes the metadata protobuf file into the dump root, and each dump may contain exactly one metadata file. If write() is called a second time after metadata was already written, an IllegalStateException is thrown. This guards the dump-format invariant that metadata appears exactly once.
Source
Thrown at server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectexport/steps/DumpWriterImpl.java:60
private final ProjectExportDumpFS projectExportDumpFS;
private final TempFolder tempFolder;
private final File rootDir;
private final AtomicBoolean metadataWritten = new AtomicBoolean(false);
private final AtomicBoolean published = new AtomicBoolean(false);
public DumpWriterImpl(ProjectDescriptor descriptor, ProjectExportDumpFS projectExportDumpFS, TempFolder tempFolder) {
this.descriptor = descriptor;
this.projectExportDumpFS = projectExportDumpFS;
this.tempFolder = tempFolder;
this.rootDir = tempFolder.newDir();
}
@Override
public void write(ProjectDump.Metadata metadata) {
checkNotPublished();
if (metadataWritten.get()) {
throw new IllegalStateException("Metadata has already been written");
}
File file = new File(rootDir, METADATA.filename());
try (FileOutputStream output = FILES2.openOutputStream(file, false)) {
PROTOBUF2.writeTo(metadata, output);
metadataWritten.set(true);
} catch (IOException e) {
throw new IllegalStateException("Can not write to file " + file, e);
}
}
@Override
public <M extends Message> StreamWriter<M> newStreamWriter(DumpElement<M> elt) {
checkNotPublished();
File file = new File(rootDir, elt.filename());
return StreamWriterImpl.create(file);
}
@OverrideView on GitHub (pinned to 184c821202)
Solutions
- Locate the duplicate call to write(metadata) — only one step should write metadata per dump
- Ensure the metadata-writing step is executed exactly once in the step sequence
- If re-exporting, create a fresh DumpWriterImpl/rootDir instead of reusing a writer that already wrote metadata
Defensive patterns
Strategy: validation
Validate before calling
// ensure metadata step runs exactly once before executing steps
if (steps.stream().filter(MetadataWritingStep.class::isInstance).count() != 1) {
throw new IllegalStateException("pipeline must contain exactly one metadata step");
} Try / catch
try { writer.write(metadata); } catch (IllegalStateException e) { logger.error("Metadata double-write; pipeline misconfigured", e); } Prevention
- Register the metadata-writing step exactly once in the export step sequence
- Never reuse a DumpWriter instance across export runs
- Track pipeline execution order in tests
When it happens
Trigger: Calling dumpWriter.write(metadata) twice in one export session — e.g. a step executed twice, or two steps both writing metadata.
Common situations: Custom export pipeline steps accidentally including a metadata-writing step more than once; re-running a failed pipeline against a DumpWriter instance that already had metadata written.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- Metadata is missing
- Dump is already published
- Ad-hoc rules export failed after processing %d rules success
- Rule Export failed after processing %d rules successfully
- Specified RuleKey '%s' is not equal to the one already regis
AI-assisted analysis of SonarSource/sonarqube@184c821202 (2026-09-09).
Data as JSON: /api/errors/e91b733bb922ae15.
Report an issue: GitHub.