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

  1. Move the preferences object into the previous argument's preferences property: verify.completions({ ..., preferences: {...} }).
  2. 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

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


AI-assisted analysis of microsoft/TypeScript@b465fdbfe1 (2026-08-12). Data as JSON: /api/errors/5ce9413b09b91f8b. Report an issue: GitHub.