microsoft/TypeScript · error · Error
Did you mean to put 'preferences' in the previous 'verify.co
Error message
Did you mean to put 'preferences' in the previous 'verify.completions' object argument instead of their own object?
What it means
Thrown by Verify.completions when called with multiple option objects and one of them (at index > 0) is a standalone preferences object (only a preferences key with no other properties). The harness detects this pattern because a lone preferences object in a subsequent slot is almost always a mistake — preferences should be nested inside the preceding completions-options argument.
Source
Thrown at src/harness/fourslashInterfaceImpl.ts:283
source: string;
description: string;
newFileContent?: string;
newRangeContent?: string;
}) => void;
}
export class Verify extends VerifyNegatable {
constructor(state: FourSlash.TestState) {
super(state);
}
public completions(...optionsArray: VerifyCompletionsOptions[]): CompletionsResult | undefined {
if (optionsArray.length === 1) {
return this.state.verifyCompletions(optionsArray[0]);
}
for (const options of optionsArray) {
if (options.preferences && Object.keys(options).length === 1 && optionsArray.length > 1 && optionsArray.indexOf(options) > 0) {
throw new Error("Did you mean to put 'preferences' in the previous 'verify.completions' object argument instead of their own object?");
}
this.state.verifyCompletions(options);
}
return {
andApplyCodeAction: () => {
throw new Error("Cannot call andApplyCodeAction on multiple completions requests");
},
};
}
public baselineInlayHints(span: ts.TextSpan, preference?: ts.UserPreferences): void {
this.state.baselineInlayHints(span, preference);
}
public quickInfoIs(expectedText: string, expectedDocumentation?: string, expectedTags?: { name: string; text: string; }[]): void {
this.state.verifyQuickInfoString(expectedText, expectedDocumentation, expectedTags);
}
View on GitHub (pinned to b465fdbfe1)
Solutions
- Move the preferences object into the previous argument's preferences property: verify.completions({ ..., preferences: {...} }).
- If you genuinely need different preference sets across completions calls, split into separate verify.completions(...) invocations.
Example fix
// before
verify.completions(
{ include: ["x"] },
{ preferences: { includeInlayParameterHints: true } }
);
// after
verify.completions({
include: ["x"],
preferences: { includeInlayParameterHints: true }
}); Defensive patterns
Strategy: type-guard
Type guard
function isPreferencesOnly(o: VerifyCompletionsOptions): o is { preferences: ts.UserPreferences } {
return !!o.preferences && Object.keys(o).length === 1;
}
// Usage: merge preferences into the preceding options object before calling
for (let i = 1; i < optionsArray.length; i++) {
if (isPreferencesOnly(optionsArray[i])) {
Object.assign(optionsArray[i - 1], optionsArray[i]);
optionsArray.splice(i, 1);
}
} Prevention
- Nest preferences inside the completions-options object it modifies rather than passing it separately.
- When refactoring a multi-arg verify.completions call, double-check that preferences land inside an options object.
When it happens
Trigger: Calling verify.completions({...}, { preferences: {...} }) where the second argument contains only preferences. The check requires options.preferences truthy, Object.keys(options).length === 1, optionsArray.length > 1, and optionsArray.indexOf(options) > 0.
Common situations: Test author splits the call into two objects intending to pass completion options and user preferences separately, rather than nesting preferences inside the first argument's preferences field.
Related errors
- Cannot call andApplyCodeAction on multiple completions reque
- verifyCurrentLineContent\n
- verifyFileContent in file '${fileName}' failed:\n${showTextD
- verifyTextAtCaretIs\n
- You need to change the source code of fourslash test to use
AI-assisted analysis of microsoft/TypeScript@b465fdbfe1 (2026-08-12).
Data as JSON: /api/errors/5ce9413b09b91f8b.
Report an issue: GitHub.