Change:
See 3rd point
Re-opening due to
I could do the check in , but I don't really understand why that's better- don't we know at the very moment is called that it's not valid to call with a cell URI?
Mostly because it doesn't break existing extensions (breaking in the sense of now throwing errors) but also to be aligned with other checks and the current behaviour (returning and logging messages). Also, for this specific case we could just be graceful and infer the notebook uri from the cell uri

Discussion:
import { FileSystemProviderErrorCode, markAsFileSystemProviderError } from 'vs/platform/files/common/files'; import { RemoteAuthorityResolverErrorCode } from 'vs/platform/remote/common/remoteAuthorityResolver'; import { IRelativePatternDto } from 'vs/workbench/api/common/extHost.protocol'; <del> import { CellEditType, ICellPartialMetadataEdit, IDocumentMetadataEdit, isTextStreamMime } from 'vs/workbench/contrib/notebook/common/notebookCommon'; </del> <ins> import { CellEditType, CellUri, ICellPartialMetadataEdit, IDocumentMetadataEdit, isTextStreamMime } from 'vs/workbench/contrib/notebook/common/notebookCommon'; </ins> import { checkProposedApiEnabled } from 'vs/workbench/services/extensions/common/extensions'; import type * as vscode from 'vscode';

edit = editOrTuple; } if (NotebookEdit.isNotebookCellEdit(edit)) { <ins> if (uri.scheme === CellUri.scheme) { throw new Error('set must be called with a notebook document URI, not a cell URI.'); } </ins> if (edit.newCellMetadata) { this.replaceNotebookCellMetadata(uri, edit.range.start, edit.newCellMetadata, metadata); } else if (edit.newNotebookMetadata) {

*--------------------------------------------------------------------------------------------*/ import * as assert from 'assert'; <del> import { URI } from 'vs/base/common/uri'; import * as types from 'vs/workbench/api/common/extHostTypes'; </del> <ins> import { CancellationError } from 'vs/base/common/errors'; import { MarshalledId } from 'vs/base/common/marshallingIds'; import { Mimes } from 'vs/base/common/mime'; </ins> import { isWindows } from 'vs/base/common/platform'; import { assertType } from 'vs/base/common/types'; <del> import { Mimes } from 'vs/base/common/mime'; import { MarshalledId } from 'vs/base/common/marshallingIds'; import { CancellationError } from 'vs/base/common/errors'; </del> <ins> import { URI } from 'vs/base/common/uri'; import * as types from 'vs/workbench/api/common/extHostTypes'; import { CellUri } from 'vs/workbench/contrib/notebook/common/notebookCommon'; </ins> function assertToJSON(a: any, expected: any) { const raw = JSON.stringify(a);

assert.strictEqual(second.edit.newText, 'Foo'); }); <ins> test('WorkspaceEdit - NotebookEdits', () => { const edit = new types.WorkspaceEdit(); const notebookEdit = types.NotebookEdit.insertCells(0, [new types.NotebookCellData(types.NotebookCellKind.Code, '// hello', 'javascript')]) as types.NotebookEdit; const notebookUri = URI.parse('/foo/notebook.ipynb'); edit.set(notebookUri, [notebookEdit]); const cellUri = CellUri.generate(notebookUri, 123); try { edit.set(cellUri, [notebookEdit]); } catch (err) { assert.ok(err.message.includes('set must be called with a notebook document URI'), err.toString()); return; } throw new Error('Expected set to throw with cell URI'); }); </ins> test('DocumentLink', () => { assert.throws(() => new types.DocumentLink(null!, null!)); assert.throws(() => new types.DocumentLink(new types.Range(1, 1, 1, 1), null!));