Skip to content

Commit 5497e5a

Browse files
committed
fix: skip local sibling probe in _preferLocalBaseForRemoteId for non-file:// schemas
When a schema is loaded from an https:// URL (e.g. via a VS Code YAML extension contributor), _preferLocalBaseForRemoteId extracts the basename from sub-schema $id values and probes for them as local siblings. This causes spurious HTTP requests that fail with 404 errors. For example, loading openapi.v3.1.yaml (with $id pointing to github.com/.../schema.yaml) from an https:// contributor causes a probe for <contributor-base>/schema.yaml, which does not exist. The companion function _resolveLocalSiblingFromRemoteUri already guards against this with `if (parentUri.scheme !== 'file') return undefined`. Apply the same scheme guard to _preferLocalBaseForRemoteId so the local sibling optimization only fires for file:// schemas where it makes sense. Made-with: Cursor
1 parent d0b52a8 commit 5497e5a

File tree

2 files changed

+48
-0
lines changed

2 files changed

+48
-0
lines changed

src/languageservice/services/yamlSchemaService.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -350,6 +350,9 @@ export class YAMLSchemaService extends JSONSchemaService {
350350
const _preferLocalBaseForRemoteId = async (currentBase: string, id: string): Promise<string> => {
351351
try {
352352
const currentBaseUri = URI.parse(currentBase);
353+
if (currentBaseUri.scheme !== 'file') {
354+
return _resolveAgainstBase(currentBase, id);
355+
}
353356
const idUri = URI.parse(id);
354357
const localFileName = path.posix.basename(idUri.path);
355358
const localDir = path.posix.dirname(currentBaseUri.path);

test/yamlSchemaService.test.ts

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -406,6 +406,51 @@ describe('YAML Schema Service', () => {
406406
expect(requestedSecondaryUrisAfterChange).to.have.length(2);
407407
});
408408

409+
it('should not probe local sibling paths when schema is loaded from https://', async () => {
410+
const content = `# yaml-language-server: $schema=https://example.com/schemas/openapi-extensions.json\nopenapi: '3.1.0'\ninfo:\n title: Test\n version: '1.0'`;
411+
const yamlDock = parse(content);
412+
413+
const extensionsSchema = {
414+
$id: 'https://example.com/schemas/openapi-extensions.json',
415+
$schema: 'http://json-schema.org/draft-04/schema#',
416+
allOf: [{ $ref: './openapi.v3.1.json' }],
417+
};
418+
const openapiSchema = {
419+
$id: 'https://github.com/OAI/OpenAPI-Specification/blob/main/schemas/v3.1/schema.json',
420+
$schema: 'https://json-schema.org/draft/2020-12/schema',
421+
type: 'object',
422+
properties: {
423+
openapi: { type: 'string', pattern: '^3\\.1\\.\\d+(-.+)?$' },
424+
info: {
425+
type: 'object',
426+
properties: { title: { type: 'string' }, version: { type: 'string' } },
427+
required: ['title', 'version'],
428+
},
429+
},
430+
required: ['openapi', 'info'],
431+
};
432+
433+
requestServiceMock = sandbox.fake((uri: string) => {
434+
if (uri === 'https://example.com/schemas/openapi-extensions.json') {
435+
return Promise.resolve(JSON.stringify(extensionsSchema));
436+
}
437+
if (uri === 'https://example.com/schemas/openapi.v3.1.json') {
438+
return Promise.resolve(JSON.stringify(openapiSchema));
439+
}
440+
return Promise.reject<string>(`Resource ${uri} not found.`);
441+
});
442+
443+
const service = new SchemaService.YAMLSchemaService(requestServiceMock, workspaceContext);
444+
await service.getSchemaForResource('', yamlDock.documents[0]);
445+
446+
const requestedUris = requestServiceMock.getCalls().map((call) => call.args[0]);
447+
expect(requestedUris).to.include('https://example.com/schemas/openapi-extensions.json');
448+
expect(requestedUris).to.include('https://example.com/schemas/openapi.v3.1.json');
449+
// _preferLocalBaseForRemoteId should NOT probe for the $id basename as a local sibling
450+
// when the parent schema was loaded from https:// (not file://)
451+
expect(requestedUris).to.not.include('https://example.com/schemas/schema.json');
452+
});
453+
409454
it('should handle modeline schema comment in the middle of file', () => {
410455
const documentContent = `foo:\n bar\n# yaml-language-server: $schema=https://json-schema.org/draft-07/schema#\naa:bbb\n`;
411456
const content = `${documentContent}`;

0 commit comments

Comments
 (0)