Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 33 additions & 1 deletion src/domains/models/SpecificationFile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,23 @@ export class Specification {
} catch {
throw new ErrorLoadingSpec('file', filepath);
}

// Detect multi-document YAML (separated by ---) and reject with a clear error.
// AsyncAPI only supports single-document YAML files. Multi-doc YAML is valid YAML
// but causes confusing low-level parser errors downstream.
// See: https://github.com/asyncapi/cli/issues/1997
const trimmed = spec.trim();
const docSeparators = (trimmed.match(/^---$/gm) || []).length;
if (docSeparators > 1) {
throw new ErrorLoadingSpec(
'file',
filepath,
`File contains multiple YAML documents (${docSeparators - 1} separators found). ` +
`AsyncAPI only supports single-document YAML files. ` +
`Please split the file or remove extra \`---\` separators.`,
);
}

return new Specification(spec, { filepath });
}

Expand Down Expand Up @@ -130,7 +147,22 @@ export class Specification {
throw new ErrorLoadingSpec('url', targetUrl);
}

return new Specification((await response?.text()) as string, {
const urlSpec = (await response?.text()) as string;

// Detect multi-document YAML (same check as fromFile)
// See: https://github.com/asyncapi/cli/issues/1997
const trimmed = urlSpec.trim();
const docSeparators = (trimmed.match(/^---$/gm) || []).length;
if (docSeparators > 1) {
throw new ErrorLoadingSpec(
'url',
targetUrl,
`URL content contains multiple YAML documents (${docSeparators - 1} separators found). ` +
`AsyncAPI only supports single-document YAML files.`,
);
}

return new Specification(urlSpec, {
fileURL: targetUrl,
});
}
Expand Down
4 changes: 2 additions & 2 deletions src/errors/specification-file.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,11 @@ export class ErrorLoadingSpec extends Error {
private readonly errorMessages = {
default: NO_CONTEXTS_SAVED,
};
constructor(from?: From, param?: string) {
constructor(from?: From, param?: string, customMessage?: string) {
super();
if (from === 'file') {
this.name = 'error loading AsyncAPI document from file';
this.message = `${param} file does not exist.`;
this.message = customMessage ?? `${param} file does not exist.`;
}
if (from === 'url') {
this.name = 'error loading AsyncAPI document from url';
Expand Down
Loading